package me.sdevil507.biz.fruit.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.*;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringTemplate;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import me.sdevil507.biz.common.sysdict.po.QSysDict;
import me.sdevil507.biz.common.sysdict.po.SysDict;
import me.sdevil507.biz.common.sysdict.service.SysdictService;
import me.sdevil507.biz.fruit.dto.*;
import me.sdevil507.biz.fruit.mapper.FruitMapper;
import me.sdevil507.biz.fruit.po.*;
import me.sdevil507.biz.fruit.repository.*;
import me.sdevil507.biz.fruit.service.FruitService;
import me.sdevil507.biz.screen.dto.ScreenSearchConditionDTO;
import me.sdevil507.org.dto.ExpertSearchDto;
import me.sdevil507.org.mapper.OrgMapper;
import me.sdevil507.org.mapper.OrgUserMapper;
import me.sdevil507.org.po.*;
import me.sdevil507.org.service.OrgRoleService;
import me.sdevil507.org.service.OrgService;
import me.sdevil507.org.service.OrgUserService;
import me.sdevil507.org.service.TempExpertService;
import me.sdevil507.supports.jpa.PageParamsDTO;
import me.sdevil507.supports.jpa.SortParamsDTO;
import me.sdevil507.supports.keywords.TfIdfAnalyzer;
import me.sdevil507.supports.shiro.helper.OrgAccountHelper;
import me.sdevil507.supports.shiro.helper.ServiceAccountHelper;
import me.sdevil507.supports.status.ComConstant;
import me.sdevil507.supports.upload.po.AttachFile;
import me.sdevil507.supports.upload.repository.AttachFileRepository;
import me.sdevil507.supports.util.ChatGptUtil;
import me.sdevil507.supports.util.CommonUtil;
import me.sdevil507.supports.util.DateUtil;
import me.sdevil507.supports.util.OrgKeyWordsUtil;
import me.sdevil507.systemAssist.Constant.SystemAssistConstant;
import me.sdevil507.systemAssist.systemMessage.Constant.SystemMessageConstant;
import me.sdevil507.systemAssist.systemMessage.po.SystemMessageTextPo;
import me.sdevil507.systemAssist.systemMessage.service.SystemMessageService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;


/**
 * @program: tips_back_end
 * @description: 实现类
 * @author: kzl
 * @create: 2020-06-23 17:38
 **/
@Service
@Slf4j
public class FruitServiceImpl implements FruitService {

    @Resource
    private FruitRepository fruitRepository;
    @Resource
    private FruitAuthorRepository fruitAuthorRepository;
    @Resource
    private FruitAuthorOrgRepository fruitAuthorOrgRepository;
    @Resource
    private FruitSubRepository fruitSubRepository;
    @Resource
    private FruitLeaderRepository fruitLeaderRepository;
    @Resource
    private FruitSpecialFeedBackRepository fruitSpecialFeedBackRepository;

    @Resource
    private FruitOrgRelRepository fruitOrgRelRepository;

    @Autowired
    private FruitWxAppletRepository fruitWxAppletRepository;

    @Resource
    private AttachFileRepository attachFileRepository;

    @Autowired
    private FruitMapper fruitMapper;

    @Autowired
    private OrgUserService orgUserService;

    @Autowired
    private SysdictService sysdictService;

    @Autowired
    JPAQueryFactory jpaQueryFactory;

    @PersistenceContext
    private EntityManager entityManager;

    @Autowired
    private TempExpertService tempExpertService;

    @Autowired
    private OrgService orgService;

    @Autowired
    private OrgMapper orgMapper;

    @Autowired
    private OrgUserMapper orgUserMapper;

    @Autowired
    private SystemMessageService messageService;
    @Autowired
    private OrgRoleService orgRoleService;
    @Autowired
    private ChatGptUtil chatGptUtil;


    //-------------------------------------------------------------------------------------------------------------------
    //----------------------------------------------------公共方法----------------------------------------------------------
    //-------------------------------------------------------------------------------------------------------------------

    /**
     * 设置id
     * @param fruitParamsDTO
     */
    @Override
    public void setBusinessId(FruitParamsDTO fruitParamsDTO){
        fruitParamsDTO.getSearchDto().setOrgId(OrgAccountHelper.getOrgId());
        fruitParamsDTO.getSearchDto().setOrgIdList(OrgAccountHelper.getOrgIdList());
        fruitParamsDTO.getSearchDto().setOrgUserId(OrgAccountHelper.getUserId());
        fruitParamsDTO.getSearchDto().setUserId(OrgAccountHelper.getUserId());
    }
    /**
     * 设置id
     * @param dto
     */
    @Override
    public void setBusinessId(FruitDTO dto){
        dto.setOrgId(OrgAccountHelper.getOrgId());
        dto.setOrgIdList(OrgAccountHelper.getOrgIdList());
        dto.setOrgUserId(OrgAccountHelper.getUserId());
        dto.setUserId(OrgAccountHelper.getUserId());
    }

    //设置全局orgId userId条件
    public Predicate buildOrgIdOrUserIdCondition(QFruitOrgRelPo qFruitOrgRelPo, QFruitPO qFruitPO, FruitDTO searchDto, String status){

        Set<Long> orgIdList = searchDto.getOrgIdList();
        Long userId = searchDto.getOrgUserId();
        int terminal = searchDto.getTerminal() == null ? 3 : searchDto.getTerminal();
        if(ComConstant.ModuleTerminal.EXPERT == terminal) {
            //专家端查询
            return qFruitOrgRelPo.fruitId.eq(qFruitPO.id)
                    .and(qFruitOrgRelPo.authUserId.eq(userId))
                    .and(qFruitOrgRelPo.status.eq(status));
        }else{
            //机构端查询--默认查询机构的成果
            return qFruitOrgRelPo.fruitId.eq(qFruitPO.id)
                    .and(qFruitOrgRelPo.orgId.in(orgIdList))
                    .and(qFruitOrgRelPo.status.eq(status));
        }
    }

    //拼装查询条件
    @Override
    public Predicate getPredicates(QFruitPO qFruitPO, FruitDTO searchDTO){
        // 开启谓语查询条件
        Predicate predicate = qFruitPO.id.isNotNull().and(qFruitPO.isDel.isFalse());

        //过滤机构 例；课题查询所有来源项目时需要过滤
//        Long orgId = searchDTO.getOrgId();
//        if (null != orgId && orgId.longValue() > 0) {
//            predicate = ExpressionUtils.and(predicate, qFruitPO.orgId.eq(orgId));
//        }

//        Long orgUserId = searchDTO.getOrgUserId();
//        if (null != orgUserId && orgUserId.longValue() > 0) {
//            predicate = ExpressionUtils.and(predicate, qFruitPO.authorPOList.any().orgUserId.eq(orgUserId));
//        }

        Long[] fruitIdList = searchDTO.getFruitIds();
        if(fruitIdList != null && fruitIdList.length > 0){
            predicate = ExpressionUtils.and(predicate, qFruitPO.id.in(fruitIdList));
        }

        Long initFruitId = searchDTO.getInitFruitId();
        if(initFruitId != null){
            predicate = ExpressionUtils.and(predicate, qFruitPO.initFruitId.eq(initFruitId));
        }

        String name = searchDTO.getName();
        if (!StringUtils.isEmpty(name)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.name.like("%" + name.trim() + "%"));
        }

        String awards = searchDTO.getAwards();
        if (!StringUtils.isEmpty(awards)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.awards.like("%" + awards.trim() + "%"));
        }

        Date startSubTime = searchDTO.getSubStartTime();
        Date endSubTime = searchDTO.getSubEndTime();
        if (null != startSubTime) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.subList.any().subTime.goe(startSubTime));
        }
        if (null != endSubTime) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.subList.any().subTime.loe(endSubTime));
        }

        Date pubStartTime = searchDTO.getPubStartTime();
        Date pubEndTime = searchDTO.getPubEndTime();
        if (null != pubStartTime) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.pubTime.goe(pubStartTime));
        }
        if (null != pubEndTime) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.pubTime.loe(pubEndTime));
        }

        Date pubStartMonth = searchDTO.getPubStartMonth();
        Date pubEndMonth = searchDTO.getPubEndMonth();
        if (null != pubStartMonth) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.pubTime.goe(DateUtil.getFirstDayDateOfMonth(pubStartMonth)));
        }
        if (null != pubEndMonth) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.pubTime.loe(DateUtil.getLastDayOfMonth(pubEndMonth)));
        }

        //批示时间
        Date pstartMonth = searchDTO.getPsStartMonth();
        Date psEndMonth = searchDTO.getPsEndMonth();
        if (null != pstartMonth) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.leaderPOS.any().inclinationTime.goe(DateUtil.getFirstDayDateOfMonth(pstartMonth)));
        }
        if (null != psEndMonth) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.leaderPOS.any().inclinationTime.loe(DateUtil.getLastDayOfMonth(psEndMonth)));
        }

        Date completionStartTime = searchDTO.getCompletionStartTime();
        Date completionEndTime = searchDTO.getCompletionEndTime();
        if (null != completionStartTime) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.pubTime.goe(completionStartTime));
        }
        if (null != completionEndTime) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.pubTime.loe(completionEndTime));
        }

        /**
         * 刊物类型
         */
        String publicationType = searchDTO.getPublicationType();
        if (!StringUtils.isEmpty(publicationType)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.publicationType.eq(publicationType));
        }

        /**
         *报告类型
         */
        String reportType = searchDTO.getReportType();
        if (!StringUtils.isEmpty(reportType)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.reportType.eq(reportType));
        }

        /**文稿类型**/
        String policyType = searchDTO.getPolicyType();
        if (!StringUtils.isEmpty(policyType)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.policyType.eq(policyType));
        }

        /**论文类型**/
        String paperType = searchDTO.getPaperType();
        if (!StringUtils.isEmpty(paperType)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.paperType.eq(paperType));
        }

        /**图书类型**/
        String bookType = searchDTO.getBookType();
        if (!StringUtils.isEmpty(bookType)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.bookType.eq(bookType));
        }

        /**媒体级别**/
        String publicationLevel = searchDTO.getPublicationLevel();
        if (!StringUtils.isEmpty(publicationLevel)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.publicationLevel.eq(publicationLevel));
        }

        /**采访媒体**/
        String organizer = searchDTO.getOrganizer();
        if (!StringUtils.isEmpty(organizer)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.organizer.like("%" + organizer.trim() + "%"));
        }

        /**奖项级别**/
        String awardsLevel = searchDTO.getAwardsLevel();
        if (!StringUtils.isEmpty(awardsLevel)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.awardsLevel.eq(awardsLevel));
        }

        /**期刊名称**/
        String journalName = searchDTO.getJournalName();
        if (!StringUtils.isEmpty(journalName)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.journalName.like("%" + journalName.trim() + "%"));
        }

        /**期刊类别**/
        String journalType = searchDTO.getJournalType();
        if (!StringUtils.isEmpty(journalType)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.journalType.like("%" + journalType.trim() + "%"));
        }

        /**访问类型**/
        String visitType = searchDTO.getVisitType();
        if (!StringUtils.isEmpty(visitType)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.visitType.like("%" + visitType.trim() + "%"));
        }

        /**起草日期**/
        Date draftTime = searchDTO.getDraftTime();
        if (draftTime != null) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.draftTime.eq(draftTime));
        }

        /**委托方等级**/
        String clientLevel = searchDTO.getClientLevel();
        if (!StringUtils.isEmpty(clientLevel)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.clientLevel.eq(clientLevel));
        }
        /**作者**/
        String author = searchDTO.getAuthor();
        if (!StringUtils.isEmpty(author)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.authorPOList.any().author.like("%" + author.trim() + "%"));
        }
        /**批示时间**/
        Date inclinationStartTime = searchDTO.getInclinationStartTime();
        Date inclinationEndTime = searchDTO.getInclinationEndTime();
        if (null != inclinationStartTime) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.leaderPOS.any().inclinationTime.goe(inclinationStartTime));
        }
        if (null != inclinationEndTime) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.leaderPOS.any().inclinationTime.loe(inclinationEndTime));
        }

        String orgName = searchDTO.getOrgName();
        if (!StringUtils.isEmpty(orgName)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.authorPOList.any().orgPOList.any().name.like("%" + orgName.trim() + "%"));
        }

        String type = searchDTO.getType();
        if (!StringUtils.isEmpty(type) && !("0").equals(type)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(type));
        }

        String notype = searchDTO.getNotype();
        if (!StringUtils.isEmpty(notype) ) {
            String[] typeList = notype.split(",");
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.notIn(typeList));
        }

        String activityProdType = searchDTO.getActivityProdType();
        if (!StringUtils.isEmpty(activityProdType)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.activityProdType.eq(activityProdType));
        }

        String isSpecialSub = searchDTO.getIsSpecialSub();
        if (!StringUtils.isEmpty(isSpecialSub)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.isSpecialSub.eq(isSpecialSub));
        }

        Integer specialSubDealStatus = searchDTO.getSpecialSubDealStatus();
        if (specialSubDealStatus != null) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.subList.any().subDeptDealStatus.eq(specialSubDealStatus));
        }

        //是否调研点建设
        String isBuildResearch = searchDTO.getIsBuildResearch();
        if (!StringUtils.isEmpty(isBuildResearch)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.isBuildResearch.eq(isBuildResearch));
        }

        Date createDate = searchDTO.getCreateDate();
        if (null!=createDate) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.createDate.eq(createDate));
        }

        String year = searchDTO.getYear();
        if(!StringUtils.isEmpty(year)){
            if(!("0").equals(year)) {
                predicate = ExpressionUtils.and(predicate, qFruitPO.pubTime.year().eq(Integer.parseInt(year)));
            }
        }

        return predicate;
    }

    @Override
    public FruitPO findOneById(long id) {
        return fruitRepository.findById(id).orElse(null);
    }

    @Override
    public List<FruitAuthorPO> getFruitAuthorById(Long id) {
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        List<FruitAuthorPO> authorPOList = jpaQueryFactory.selectFrom(qFruitAuthorPO)
                .where(qFruitAuthorPO.fruitId.eq(id).and(qFruitAuthorPO.isDel.isFalse())).fetch();

        return authorPOList;
    }

    @Override
    public Boolean getFruitByAuthorId(Long id) {
        boolean flag = false;
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        //查询作者关联的作者成果信息
        List<Long> fruitIdList = jpaQueryFactory.select(qFruitAuthorPO.fruitId).from(qFruitAuthorPO)
                .where(qFruitAuthorPO.orgUserId.eq(id).and(qFruitAuthorPO.isDel.isFalse())).fetch();
        if(!CollectionUtils.isEmpty(fruitIdList)){
            //查询成果是否被删除
            long count = jpaQueryFactory.selectFrom(qFruitPO).where(qFruitPO.id.in(fruitIdList).and(qFruitPO.isDel.isFalse())).fetchCount();
            return count > 0;
        }
        return false;
    }

    /**
     * 查询成果公共方法
     * @param searchDTO
     * @param sortParamsDto
     * @return
     */
    private JPAQuery<ResultListFruitDTO> commonSearchFruitListMethod(FruitDTO searchDTO, SortParamsDTO sortParamsDto){
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        // 开启谓语查询条件
        Predicate predicate = getPredicates(qFruitPO, searchDTO);

        //专家端首页按 第一作者 查询
        String authorSort = searchDTO.getAuthorSort();
        if(("1").equals(authorSort)) {
            //查询所有是当前专家为第一作者的成果
            List<Long> fruitIdList = jpaQueryFactory.select(qFruitAuthorPO.fruitId).from(qFruitAuthorPO)
                    .where(qFruitAuthorPO.ranking.eq(1)
                            .and(qFruitAuthorPO.orgUserId.eq(searchDTO.getOrgUserId()))
                    ).fetch();
            predicate = ExpressionUtils.and(predicate, qFruitPO.id.in(fruitIdList));
        }

        //子查询 作者
        StringTemplate authorExpr = Expressions.stringTemplate("CONCAT(GROUP_CONCAT({0}),'')", qFruitAuthorPO.author);
        SubQueryExpression queryAuthor = JPAExpressions.select(authorExpr.as("authors")).from(qFruitAuthorPO)
                .where(qFruitAuthorPO.fruitId.eq(qFruitOrgRelPo.fruitId)).orderBy(qFruitAuthorPO.ranking.asc());

        return jpaQueryFactory.select(
                Projections.constructor(ResultListFruitDTO.class,
                        qFruitPO.id,
                        qFruitPO.name,
                        qFruitPO.type,
                        qFruitPO.activityProdType,
                        qFruitPO.pubTime,
                        qFruitPO.completionTime,
                        queryAuthor,
                        qFruitPO.journalName,
                        qFruitPO.issueNumber,
                        qFruitPO.press,
                        qFruitPO.isbn,
                        qFruitPO.meetingTypeName,
                        qFruitPO.organizer,
                        qFruitPO.visitTypeName,
                        qFruitPO.awards,
                        qFruitPO.grantUnit,
                        qFruitPO.projectStatusName,
                        qFruitPO.clientLevelName,
                        qFruitPO.topicName
                )
        )
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(buildOrgIdOrUserIdCondition(qFruitOrgRelPo, qFruitPO, searchDTO, ComConstant.FruitStatus.APPROVED))
                .where(predicate)
                .orderBy(
                        qFruitPO.pubTime.desc()
                );
    }

    /**
     * 成果列表菜单分页查询
     * @param searchDTO
     * @param pageParamsDto
     * @param sortParamsDto
     * @return
     */
    @Override
    public Page<ResultListFruitDTO> readAllFruitByPage(FruitDTO searchDTO, PageParamsDTO pageParamsDto, SortParamsDTO sortParamsDto) {
        Pageable pageable = pageParamsDto.getPageable();

        QueryResults<ResultListFruitDTO> queryResults = this.commonSearchFruitListMethod(searchDTO, sortParamsDto)
                .offset(pageable.getPageNumber() * pageable.getPageSize())
                .limit(pageable.getPageSize())
                .fetchResults();

        return  new PageImpl<>(queryResults.getResults(), pageable, queryResults.getTotal());
    }


    /**
     * 专报内参 分页查询
     * @param searchDTO
     * @param pageParamsDto
     * @param sortParamsDto
     * @return
     */
    @Override
    public Page<ResultListFruitDTO> readAllOrgSpecialFruitByPage(FruitDTO searchDTO, PageParamsDTO pageParamsDto, SortParamsDTO sortParamsDto) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        QFruitFeedBackPO qFruitFeedBackPO = QFruitFeedBackPO.fruitFeedBackPO;
        // 开启谓语查询条件
        Predicate predicate = getPredicates(qFruitPO, searchDTO);
        // 执行返回
        Pageable pageable = pageParamsDto.getPageable();

        //子查询 作者
        StringTemplate authorExpr = Expressions.stringTemplate("CONCAT(GROUP_CONCAT({0}),'')", qFruitAuthorPO.author);
        SubQueryExpression queryAuthor = JPAExpressions.select(authorExpr.as("authors")).from(qFruitAuthorPO)
                .where(qFruitAuthorPO.fruitId.eq(qFruitOrgRelPo.fruitId));

        //子查询 是否有反馈
//        StringTemplate feedBackExpr = Expressions.stringTemplate("COUNT({0})", qFruitFeedBackPO.id);
//        SubQueryExpression queryFeedBack = JPAExpressions.select(feedBackExpr.as("feedBackCount")).from(qFruitFeedBackPO)
//                .where(qFruitFeedBackPO.fruitId.eq(qFruitOrgRelPo.fruitId)
//                        .and(qFruitFeedBackPO.type.eq("2")
//                                .and(qFruitFeedBackPO.isLook.isFalse()))
//                );
        JPAQuery<ResultListFruitDTO> queryResults = jpaQueryFactory.select(
                Projections.constructor(ResultListFruitDTO.class,
                        qFruitPO.id,
                        qFruitPO.name,
                        qFruitPO.type,
                        qFruitPO.activityProdType,
                        qFruitPO.pubTime,
                        queryAuthor,
                        qFruitPO.topicName
                )
        )
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(
                        buildOrgIdOrUserIdCondition(qFruitOrgRelPo, qFruitPO, searchDTO, ComConstant.FruitStatus.APPROVED)
                )
                .where(predicate)
                .orderBy(
                        ("asc").equals(sortParamsDto.getSortDirection())?qFruitPO.pubTime.asc():qFruitPO.pubTime.desc()
                );
        //查询反馈数量
        List<ResultListFruitDTO> fruitDTOS = new ArrayList<>();
        queryResults.fetch().stream().forEach(resultListFruitDTO -> {
            Long feedBackCount = jpaQueryFactory.select(qFruitFeedBackPO.id).from(qFruitFeedBackPO)
                    .where(qFruitFeedBackPO.fruitId.eq(resultListFruitDTO.getId())
                            .and(qFruitFeedBackPO.type.eq("2").and(qFruitFeedBackPO.isLook.isFalse()))).fetchCount();
            resultListFruitDTO.setFeedBackCount(feedBackCount != null ? feedBackCount.intValue() : 0);
            fruitDTOS.add(resultListFruitDTO);
        });

        //反馈排序
        List<ResultListFruitDTO> list = fruitDTOS.stream().sorted(Comparator.comparing(ResultListFruitDTO::getFeedBackCount).reversed()).collect(Collectors.toList());

        //分页
        int fromIndex = pageable.getPageSize()*pageable.getPageNumber();
        int toIndex = pageable.getPageSize()*(pageable.getPageNumber()+1);
        //#获取当前页数据
        toIndex = list.size() >= toIndex ? toIndex : list.size();

        List<ResultListFruitDTO> resultList = list.subList(fromIndex,toIndex);

        return new PageImpl<>(resultList, pageable, list.size());
    }

    @Override
    public List<FruitFeedBackPO> getOneFruitFeedBackByFruitId(FruitFeedBackPO fruitFeedBackPO) {
        return fruitSpecialFeedBackRepository.getAllByFruitIdOrderByCreateTimeDesc(fruitFeedBackPO.getFruitId());
    }

    /**
     * 首页查询成果分页
     * @param searchDTO
     * @param pageParamsDto
     * @param sortParamsDto
     * @return
     */
    @Override
    public Page<ResultListFruitDTO> readAllHomeFruitByPage(FruitDTO searchDTO, PageParamsDTO pageParamsDto, SortParamsDTO sortParamsDto) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;
        // 开启谓语查询条件
        Predicate predicate = getPredicates(qFruitPO, searchDTO);

        return getHomeFruit(qFruitPO, predicate, searchDTO, pageParamsDto, sortParamsDto);
    }

    /**
     * 首页高级搜索查询成果分页
     * @return
     */
    @Override
    public Page<ResultListFruitDTO> readAllHomeFruitOfSearchByPage(FruitParamsDTO fruitParamsDTO) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;
        FruitDTO searchDTO = fruitParamsDTO.getSearchDto();
        // 开启谓语查询条件
        Predicate predicate = qFruitPO.id.isNotNull().and(qFruitPO.isDel.isFalse());

        /**
         *搜索内容---名称和专家名
         */
        String content = fruitParamsDTO.getHomeSearchDto().getContent();
        if (!StringUtils.isEmpty(content)) {
            predicate = ExpressionUtils.and(
                    predicate,
                    qFruitPO.name.like("%" + content.trim() + "%")
                            .or(qFruitPO.summary.like("%" + content.trim() + "%"))
                            .or(qFruitPO.remark.like("%" + content.trim() + "%"))
                            .or(qFruitPO.awards.like("%" + content.trim() + "%"))
                            .or(qFruitPO.theme.like("%" + content.trim() + "%"))
                            .or(qFruitPO.authorPOList.any().author.like("%" + content.trim() + "%"))
            );
        }
        //成果类型
        String[] typeArr = fruitParamsDTO.getHomeSearchDto().getTypeArr();
        if(typeArr != null && typeArr.length > 0){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.in(typeArr));
        }

        //发表时间
        Date pubStartTime = searchDTO.getPubStartTime();
        Date pubEndTime = searchDTO.getPubEndTime();
        if (null != pubStartTime) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.pubTime.goe(pubStartTime));
        }
        if (null != pubEndTime) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.pubTime.loe(pubEndTime));
        }
        return getHomeFruit(qFruitPO, predicate, fruitParamsDTO.getSearchDto(), fruitParamsDTO.getPageDto(), fruitParamsDTO.getSortDto());
    }


    public Page<ResultListFruitDTO> getHomeFruit(QFruitPO qFruitPO, Predicate predicate, FruitDTO searchDTO, PageParamsDTO pageParamsDto, SortParamsDTO sortParamsDto){
        QFruitSubPO qFruitSubPO = QFruitSubPO.fruitSubPO;

        Pageable pageable = pageParamsDto.getPageable();

        QueryResults<ResultListFruitDTO> queryResults = this.commonSearchFruitListMethod(searchDTO, sortParamsDto)
                .offset(pageable.getPageNumber() * pageable.getPageSize())
                .limit(pageable.getPageSize())
                .fetchResults();

        //获取最高等级报送部门
        queryResults.getResults().stream().forEach(resultListFruitDTO -> {
            //只查询内参
            if(resultListFruitDTO.getType().equals(ComConstant.FruitType.InternalReferenceReport)){
                List<FruitSubPO> depts = jpaQueryFactory.select(qFruitSubPO).from(qFruitSubPO)
                        .where(qFruitSubPO.fruitId.eq(resultListFruitDTO.getId()))
                        .orderBy(qFruitSubPO.level.asc()).fetch();
                if(!CollectionUtils.isEmpty(depts)){
                    resultListFruitDTO.setSubLevel(depts.get(0).getSubDeparment());
                }
            }
        });

        return new PageImpl<>(queryResults.getResults(), pageable, queryResults.getTotal());
    }

    /**
     * 专家端查询所有成果
     * @param searchDTO 搜索DTO
     * @param sortParamsDto   排序DTO
     * @return
     */
    @Override
    public List<ResultListFruitDTO> readAll(FruitDTO searchDTO, SortParamsDTO sortParamsDto) {

        QueryResults<ResultListFruitDTO> queryResults = this.commonSearchFruitListMethod(searchDTO, sortParamsDto).fetchResults();

        return queryResults.getResults();
    }

    /**
     * 查询所有成果的分支
     * @param searchDTO 搜索DTO
     * @return
     */
    @Override
    public List<ResultTagFruitDTO> readAllTagFruitList(FruitDTO searchDTO) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;

        return jpaQueryFactory.select(
                        Projections.constructor(ResultTagFruitDTO.class,
                                qFruitPO.id,
                                qFruitPO.name,
                                qFruitPO.createTime,
                                qFruitPO.orgName,
                                qFruitPO.userName
                        )
                )
                .from(qFruitPO)
                .where(qFruitPO.initFruitId.eq(searchDTO.getInitFruitId()).and(qFruitPO.isDel.isFalse()))
                .orderBy(qFruitPO.createTime.desc())
                .fetch();
    }

    @Override
    public FruitPO findIsExistFruit(FruitDTO dto){
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        Predicate predicate = qFruitPO.id.isNotNull().and(qFruitPO.isDel.isFalse()).and(qFruitPO.isPublic.eq("0"))
                .and(qFruitPO.name.eq(dto.getName().trim())).and(qFruitPO.type.eq(dto.getType()));
        if(dto.getId() != null){
            predicate = ExpressionUtils.and(predicate, qFruitPO.id.ne(dto.getId()));
        }
        if(ComConstant.ModuleTerminal.ORGANIZATION == dto.getTerminal()) {
            return jpaQueryFactory.select(qFruitPO)
                    .from(qFruitOrgRelPo)
                    .leftJoin(qFruitPO).on(qFruitPO.id.eq(qFruitOrgRelPo.fruitId)).on(qFruitOrgRelPo.orgId.eq(dto.getOrgId())
                            .and(qFruitOrgRelPo.status.eq(ComConstant.FruitStatus.APPROVED))).where(predicate).fetchOne();

        }else{
            return jpaQueryFactory.select(qFruitPO)
                    .from(qFruitOrgRelPo)
                    .leftJoin(qFruitPO).on(qFruitPO.id.eq(qFruitOrgRelPo.fruitId)).on(qFruitOrgRelPo.authUserId.eq(dto.getOrgUserId())
                            .and(qFruitOrgRelPo.status.eq(ComConstant.FruitStatus.APPROVED))).where(predicate).fetchOne();
        }
    }

    @Override
    public Integer readAllOrgSpecialFruitFeedBackCount(FruitDTO searchDTO) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        QFruitFeedBackPO qFruitFeedBackPO = QFruitFeedBackPO.fruitFeedBackPO;
        // 开启谓语查询条件
        Predicate predicate = getPredicates(qFruitPO, searchDTO);
        //所有专报内参id
        List<Long> fruitIds = jpaQueryFactory.select(qFruitPO.id)
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(
                        buildOrgIdOrUserIdCondition(qFruitOrgRelPo, qFruitPO, searchDTO, ComConstant.FruitStatus.APPROVED)
                )
                .where(predicate).fetch();
        //查询反馈
        Long count = jpaQueryFactory.selectFrom(qFruitFeedBackPO).where(qFruitFeedBackPO.fruitId.in(fruitIds)
                .and(qFruitFeedBackPO.type.eq("2")
                        .and(qFruitFeedBackPO.isLook.isFalse()))).fetchCount();

        return count.intValue();
    }

    /**
     * 新增成果新分支信息
     * @param fruitDTO
     * @param orgId
     * @param userId
     */
    private FruitPO createNewFruit(FruitDTO fruitDTO, Long orgId, Long userId) {
        ObjectMapper objMapper = new ObjectMapper();
        FruitPO newFruitPO = null;
        try {
            //---更新最初版本的报送批示信息
            FruitPO fruitOldPo = fruitRepository.getOne(fruitDTO.getInitFruitId());
            //公共数据  不需要新增
            fruitOldPo.getSubList().clear();
            fruitOldPo.getLeaderPOS().clear();
            fruitOldPo.getMemberList().clear();
            fruitOldPo.getSubprojectList().clear();
            fruitOldPo.getSubList().addAll(fruitDTO.getSubList());
            fruitOldPo.getLeaderPOS().addAll(fruitDTO.getLeaderPOS());
            fruitOldPo.getMemberList().addAll(fruitDTO.getMemberList());
            fruitOldPo.getSubprojectList().addAll(fruitDTO.getSubprojectList());
            fruitRepository.save(fruitOldPo);

            //---更新基础信息
            //深拷贝
            newFruitPO = objMapper.readValue(objMapper.writeValueAsString(fruitDTO), FruitPO.class);
            newFruitPO.setId(null);
            newFruitPO.setOrgId(orgId);
            newFruitPO.setUserId(userId);
            newFruitPO.setCreateTime(new Date());
            newFruitPO.setUpdateTime(new Date());
            //公共数据  不需要新增
            newFruitPO.getSubList().clear();
            newFruitPO.getLeaderPOS().clear();
            newFruitPO.getMemberList().clear();
            newFruitPO.getSubprojectList().clear();
            //设置新附件
            List<AttachFile> newAttFiles = new ArrayList<>();
            newFruitPO.getAttFiles().forEach(att->{
                AttachFile attachFile = new AttachFile();
                BeanUtils.copyProperties(att, attachFile);
                attachFile.setId(null);
                attachFile = attachFileRepository.save(attachFile);
                newAttFiles.add(attachFile);
            });
            newFruitPO.setAttFiles(newAttFiles);
            //设置作者
            List<FruitAuthorPO> newAuthorPOList = new ArrayList<>();
            newFruitPO.getAuthorPOList().forEach(oldAuthorPO->{
                FruitAuthorPO fruitAuthorPO = new FruitAuthorPO();
                BeanUtils.copyProperties(oldAuthorPO, fruitAuthorPO);
                fruitAuthorPO.setId(null);
                fruitAuthorPO.setFruitId(null);
    //                fruitAuthorPO = fruitAuthorRepository.save(fruitAuthorPO);
    //                Long authorId = fruitAuthorPO.getId();

                //设置作者单位
                List<FruitAuthorOrgPO> newAuthorOrgPOList = new ArrayList<>();
                oldAuthorPO.getOrgPOList().forEach(oldAuthorOrgPO->{
                    FruitAuthorOrgPO fruitAuthorOrgPO = new FruitAuthorOrgPO();
                    BeanUtils.copyProperties(oldAuthorOrgPO, fruitAuthorOrgPO);
                    fruitAuthorOrgPO.setId(null);
                    fruitAuthorOrgPO.setAuthorId(null);
    //                    fruitAuthorOrgPO = fruitAuthorOrgRepository.save(fruitAuthorOrgPO);
                    newAuthorOrgPOList.add(fruitAuthorOrgPO);
                });
                fruitAuthorPO.setOrgPOList(newAuthorOrgPOList);
                newAuthorPOList.add(fruitAuthorPO);
            });
            newFruitPO.getAuthorPOList().clear();
            newFruitPO.getAuthorPOList().addAll(newAuthorPOList);
            //保存新版本
            fruitRepository.save(newFruitPO);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return newFruitPO;
    }


    //-------------------------------------------------------------------------------------------------------------------
    //----------------------------------------------------机构端----------------------------------------------------------
    //-------------------------------------------------------------------------------------------------------------------

    /**
     * 机构端 待审核列表查询
     * @param searchDTO
     * @param pageParamsDto
     * @param sortParamsDto
     * @return
     */
    @Override
    public Page<ResultWaitCheckFruitDTO> readAllOrgFruitWaitingCheckByPage(FruitDTO searchDTO, PageParamsDTO pageParamsDto, SortParamsDTO sortParamsDto) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;

        Pageable pageable = pageParamsDto.getPageable();

        QueryResults<ResultWaitCheckFruitDTO> queryResults = jpaQueryFactory.select(
                Projections.constructor(ResultWaitCheckFruitDTO.class,
                        qFruitPO.id,
                        qFruitPO.name,
                        qFruitPO.type,
                        qFruitPO.activityProdType,
                        qFruitPO.pubTime,
                        qFruitPO.orgName,
                        qFruitPO.userName
                )
        )
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(
                        buildOrgIdOrUserIdCondition(qFruitOrgRelPo, qFruitPO, searchDTO, ComConstant.FruitStatus.WATICHECK)
                )
                .where(qFruitPO.isDel.isFalse())
                .orderBy(qFruitPO.pubTime.desc())
                .offset(pageable.getPageNumber() * pageable.getPageSize())
                .limit(pageable.getPageSize())
                .fetchResults();

        return  new PageImpl<>(queryResults.getResults(), pageable, queryResults.getTotal());
    }

    /**
     * 机构端成果列表菜单分页查询--课题选择时  选择成果不在课题列表中的
     * @param searchDTO
     * @param pageParamsDto
     * @param sortParamsDto
     * @return
     */
    @Override
    public Page<FruitPO> searchFruitNotInProjectData(FruitDTO searchDTO, PageParamsDTO pageParamsDto, SortParamsDTO sortParamsDto) {

//        QFruitPO qFruitPO = QFruitPO.fruitPO;
//        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
//        QProjectPo qProjectPo = QProjectPo.projectPo;
//        // 开启谓语查询条件
//        Predicate predicate = getPredicates(qFruitPO, searchDTO);
//        // 执行返回
//        Pageable pageable = pageParamsDto.getPageable();
//
//        //查询机构下所有的课题对应的成果
//        List<Long> fruitIdList = jpaQueryFactory.select(qProjectPo.fruitId).from(qProjectPo)
//                .where(qProjectPo.isDel.isFalse().and(qProjectPo.orgId.in(searchDTO.getOrgIdList())))
//                .fetch();
//
//        QueryResults<FruitPO> queryResults = jpaQueryFactory.select(qFruitPO)
//                .from(qFruitOrgRelPo)
//                .leftJoin(qFruitPO).on(
//                        buildOrgIdOrUserIdCondition(qFruitOrgRelPo, qFruitPO, searchDTO, ComConstant.FruitStatus.APPROVED)
//                )
//                .where(predicate)
//                .where(qFruitPO.id.notIn(fruitIdList))
//                .orderBy(
//                        ("asc").equals(sortParamsDto.getSortDirection())?qFruitPO.pubTime.asc():qFruitPO.pubTime.desc()
//                )
//                .offset(pageable.getPageNumber() * pageable.getPageSize())
//                .limit(pageable.getPageSize())
//                .fetchResults();
//
//        return  new PageImpl<>(queryResults.getResults(), pageable, queryResults.getTotal());
        return null;
    }


    /**
     * 判断是否已经报送到 江苏省委宣传部(智库专报途径)
     * @param fruitSubPOList
     * @return
     */
    @Override
    public boolean isHaveBsJSSWXCB(List<FruitSubPO> fruitSubPOList){
        boolean flag = false;
        if(!CollectionUtils.isEmpty(fruitSubPOList)){
            for (FruitSubPO fruitSubPO : fruitSubPOList) {
                if((ComConstant.specialDeptName.JSSWXCB).equals(fruitSubPO.getSubDeparment()) && fruitSubPO.getSubDeptType() != null && fruitSubPO.getSubDeptType() == 1 ){
                    flag = true;
                    break;
                }
            }
        }
        return flag;
    }

    /**
     * 机构新增成果
     * @param fruitDTO
     */
    @Override
    public void orgCreate(FruitDTO fruitDTO) {
        Long userId = OrgAccountHelper.getUserId();
        String userName = orgUserService.readOneById(userId).getRealName();
        Long orgId = OrgAccountHelper.getOrgId();

        //判断是否修改过智库专报
//        boolean isModifySpecial = this.isEditSpecialSub(fruitDTO);

        FruitPO fruitPo = null;
        //新增成果时
        if(fruitDTO.getId() == null){
            //补充新增或修改成机构人员信息
            fruitDTO.setUserId(userId);
            fruitDTO.setUserName(userName);
            fruitDTO.setOrgId(orgId);
            fruitPo = fruitRepository.save(fruitMapper.dto2po(fruitDTO));

            //更新成果的初始id
            fruitPo.setInitFruitId(fruitPo.getId());
            fruitRepository.save(fruitPo);
        }else{
            // -------------修改-------------
            //新版本--第一版不是当前机构新增的  新增新版本数据---更新基础信息
//            if(fruitDTO.isEdit() && !orgId.equals(fruitDTO.getOrgId())){
//                fruitPo = this.orgCreateNewFruit(fruitDTO, orgId);
//            }else{
                fruitPo = fruitRepository.save(fruitMapper.dto2po(fruitDTO));
//            }
            //先删除关键字
//            wordcloudService.deleteByFruitId(fruitPo.getId());
        }
        //新增机构与成果关系
        this.orgCreateFruitOrgRelation(fruitPo);
        //新增专家与成果关系
        this.orgCreateFruitExpertRelation(fruitPo);

        //设置成果关键字
//        wordcloudService.create(fruitPo.getId());
    }

    /**
     * 机构新增新版本成果
     * @param fruitDTO
     */
    public FruitPO orgCreateNewFruit(FruitDTO fruitDTO, Long orgId){
        FruitPO newFruitPO = null;
        try {
            newFruitPO = this.createNewFruit(fruitDTO, orgId, null);
            //更新关联关系的parentId
            QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
            FruitOrgRelPo fruitOrgRelPo = jpaQueryFactory.selectFrom(qFruitOrgRelPo)
                    .where(qFruitOrgRelPo.orgId.eq(orgId).and(qFruitOrgRelPo.fruitId.eq(fruitDTO.getId())))
                    .fetchOne();
            if(fruitOrgRelPo != null){
                fruitOrgRelPo.setFruitId(newFruitPO.getId());
                fruitOrgRelRepository.save(fruitOrgRelPo);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return newFruitPO;
    }

    /**
     * 机构新增成果与机构匹配关系
     * @param fruitPO
     */
    public void orgCreateFruitOrgRelation(FruitPO fruitPO){
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        long count = jpaQueryFactory.selectFrom(qFruitOrgRelPo).where(qFruitOrgRelPo.orgId.eq(OrgAccountHelper.getOrgId()).and(qFruitOrgRelPo.fruitId.eq(fruitPO.getId()))).fetchCount();
        if (count == 0) {
            //添加机构与成果的对应关系
            this.createFruitOrgOrExpertRel(OrgAccountHelper.getOrgId(), null, fruitPO.getId(), fruitPO.getInitFruitId(), ComConstant.FruitStatus.APPROVED);
        }

//        List<String> addOrgNames = new ArrayList<>();
//        //获取提交成果的机构单位名称
//        fruitPO.getAuthorPOList().forEach(authorPO-> {
//            authorPO.getOrgPOList().forEach(orgPo->{
//                addOrgNames.add(orgPo.getName());
//            });
//        });
//
//        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
//        if(!CollectionUtils.isEmpty(addOrgNames)){
//            //获取所有机构关键词map
//            Map<OrgPo, List<OrgKeywordPo>> orgKeywordsMap = this.getAllOrgKeyWords();
//            addOrgNames.forEach(orgName -> {
//                Long sendOrgId = this.matchKeyWordsAndGetOrgId(orgKeywordsMap, orgName);
//                //如果匹配上,那就保存机构与成果的对应关系
//                if (sendOrgId != null) {
//                    //判断是否已经存在--因全职机构名称和专家填写的名称 可能不一样但却是同一个机构（上面的去重不了）
//                    long count = jpaQueryFactory.selectFrom(qFruitOrgRelPo).where(qFruitOrgRelPo.orgId.eq(sendOrgId).and(qFruitOrgRelPo.fruitId.eq(fruitPO.getId()))).fetchCount();
//                    if (count == 0) {
//                        //去除当前机构---因为是当前机构自己添加，不需要通知
//                        if(fruitPO.getOrgId().equals(sendOrgId)){
//                            //添加机构与成果的对应关系
//                            this.createFruitOrgOrExpertRel(sendOrgId, null, fruitPO.getId(), fruitPO.getInitFruitId(), ComConstant.FruitStatus.APPROVED);
//                            //消息通知管理部门
//                            this.sendMessageToOrgMangers(fruitPO, OrgAccountHelper.getUserId(), OrgAccountHelper.getOrgId(),
//                                    SystemAssistConstant.systemAssistTerminal.SERVICES);
//                        }else{
//                            //判断机构是否已经添加过对应关系
//                            long fruitCount = jpaQueryFactory.selectFrom(qFruitOrgRelPo).where(qFruitOrgRelPo.orgId.eq(sendOrgId).and(qFruitOrgRelPo.initFruitId.eq(fruitPO.getInitFruitId()))).fetchCount();
//                            if(fruitCount == 0){
//                                //添加机构与成果的对应关系
//                                this.createFruitOrgOrExpertRel(sendOrgId, null, fruitPO.getId(), fruitPO.getInitFruitId(), ComConstant.FruitStatus.WATICHECK);
//                                //消息通知别的部门
//                                this.sendMessageToOrg(fruitPO, OrgAccountHelper.getUserId(), OrgAccountHelper.getOrgId(), sendOrgId,
//                                        SystemAssistConstant.systemAssistTerminal.ORG);
//                            }
//                        }
//                    }
//                }
//            });
//        }
    }

    /**
     * 获取所有机构关键词map
     * @return
     */
    public Map<OrgPo, List<OrgKeywordPo>> getAllOrgKeyWords(){
        Long orgId = null;
        //查询所有机构的关键词---一个机构对应多个关键字
        QOrgKeywordPo qOrgKeywordPo = QOrgKeywordPo.orgKeywordPo;
        List<OrgKeywordPo> keywordsList = jpaQueryFactory.select(qOrgKeywordPo).from(qOrgKeywordPo).fetch();
        //分组
        return keywordsList.stream().collect(Collectors.groupingBy(OrgKeywordPo::getOrg));
    }

    /**
     * 机构匹配关键词并返回匹配上的机构id
     * @param matchWord
     * @return
     */
    public Long matchKeyWordsAndGetOrgId(Map<OrgPo, List<OrgKeywordPo>> keywordsMap, String matchWord){
        Long orgId = null;
        for (OrgPo orgPo : keywordsMap.keySet()) {
            Set<String> keywordNames = orgPo.getKeywords().stream().map(OrgKeywordPo::getName).collect(Collectors.toSet());
            if (OrgKeyWordsUtil.matchKeyWords(matchWord, keywordNames)) {
                orgId = orgPo.getId();
                break;
            }
        }
        return orgId;
    }

    /**
     * 新增成果与专家匹配关系
     * @param fruitPO
     */
    public void orgCreateFruitExpertRelation(FruitPO fruitPO){
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        fruitPO.getAuthorPOList().forEach(authorPO-> {
            //乱填姓名匹配不上  需加上判断
            if(!ObjectUtil.isEmpty(authorPO.getOrgUserId())){
                //判断专家是否已经添加过对应关系
                long fruitCount = jpaQueryFactory.selectFrom(qFruitOrgRelPo).where(qFruitOrgRelPo.authUserId.eq(authorPO.getOrgUserId()).and(qFruitOrgRelPo.initFruitId.eq(fruitPO.getInitFruitId()))).fetchCount();
                if(fruitCount == 0){
                    //新增专家与成果的关系--不需要填写orgId, 机构查询方便过滤
                    this.createFruitOrgOrExpertRel(null, authorPO.getOrgUserId(), fruitPO.getId(), fruitPO.getInitFruitId(), ComConstant.FruitStatus.APPROVED);
                    //消息通知
                    this.sendMessageToExpert(fruitPO, OrgAccountHelper.getUserId(), OrgAccountHelper.getOrgId(), authorPO.getOrgUserId(),
                            SystemAssistConstant.systemAssistTerminal.EXPERT);
                }
            }
        });
    }


    /**
     * 报送到智库专报
     * @param fruitDTO
     */
    @Override
    public void subNcToSpecial(FruitDTO fruitDTO) {
        FruitPO oldFruitPO = fruitRepository.getOne(fruitDTO.getId());
        //判断是否修改过智库专报
        boolean isModifySpecial = this.isEditSpecialSub(oldFruitPO, fruitDTO);

        oldFruitPO.getAttFiles().addAll(fruitDTO.getAttFiles());
        oldFruitPO.setIsSpecialSub(fruitDTO.getIsSpecialSub());
        oldFruitPO.setBodyText(fruitDTO.getBodyText());

        //判断是否已经报送到 江苏省委宣传部(智库专报途径)
        boolean flag = isHaveBsJSSWXCB(oldFruitPO.getSubList());
        if(!flag){
            //如果没有 新增报送信息
            this.saveBsInfo(oldFruitPO.getId());
        }
        //添加专报过程记录
        if(isModifySpecial) {
            this.orgAddSpecialData(oldFruitPO, OrgAccountHelper.getOrgId());
        }
        fruitRepository.save(oldFruitPO);
    }


    /**
     * 是否修改过专报
     * @param fruitDTO
     * @return
     */
    public boolean isEditSpecialSub(FruitPO oldFruitPO, FruitDTO fruitDTO) {
        fruitDTO.setSpecialSubSource("1");
        //旧专报内容和附件
        String oldBodyText = oldFruitPO.getBodyText();
        List<AttachFile> oldAttFiles = oldFruitPO.getAttFiles().stream().filter(attachFile -> attachFile.getType().equals(ComConstant.AttFileType.SPECIALREPORT)).collect(Collectors.toList());
        String oldAttFilePath = "";
        if (!CollectionUtils.isEmpty(oldAttFiles)) {
            oldAttFilePath = oldAttFiles.get(0).getPath();
        }
        //新专报内容和附件
        String newBodyText = fruitDTO.getBodyText();
        String newAttFilePath = "";
        if (!CollectionUtils.isEmpty(fruitDTO.getAttFiles())) {
            newAttFilePath = fruitDTO.getAttFiles().get(0).getPath();
        }
        //比较
        return !oldBodyText.equals(newBodyText) || !oldAttFilePath.equals(newAttFilePath);
    }


    /**
     * 新增报送信息(专报)
     * @param fruitId
     */
    @Override
    public void saveBsInfo(long fruitId){
        FruitSubPO fruitSubPO = new FruitSubPO();
        fruitSubPO.setFruitId(fruitId);
        fruitSubPO.setSubTime(new Date());
        fruitSubPO.setSubDeparment(ComConstant.specialDeptName.JSSWXCB);
        fruitSubPO.setIsAdopt(false);
        fruitSubPO.setLevel("4");
        fruitSubPO.setSubDeptType(1);
        fruitSubPO.setSubDeptDealStatus(0);
        fruitSubRepository.save(fruitSubPO);
    }

    /**
     * 添加专报过程记录
     */
    @Override
    public void orgAddSpecialData(FruitPO fruitPO, Long orgId){
        FruitFeedBackPO fruitFeedBackPO = new FruitFeedBackPO();
        fruitFeedBackPO.setCreateTime(new Date());
        fruitFeedBackPO.setFruitId(fruitPO.getId());
        fruitFeedBackPO.setOrgId(orgId);
        //机构
        OrgPo orgPo = orgService.readOne(orgId);
        fruitFeedBackPO.setSourceName(orgPo.getShortNameZh());
        fruitFeedBackPO.setIsDel(false);
        fruitFeedBackPO.setType("1");
        fruitFeedBackPO.setBodyText(fruitPO.getBodyText());
        fruitFeedBackPO.setIsLook(false);

        List<AttachFile> fruitAttachFiles = fruitPO.getAttFiles().stream().filter(attachFile -> attachFile.getType().equals(ComConstant.AttFileType.SPECIALREPORT)).collect(Collectors.toList());
        List<AttachFile> newAttList = new ArrayList<>();
        fruitAttachFiles.forEach(att->{
            AttachFile attachFile = new AttachFile();
            BeanUtils.copyProperties(att, attachFile);
            attachFile.setId(null);
            attachFile = attachFileRepository.save(attachFile);
            newAttList.add(attachFile);
        });
        fruitFeedBackPO.setAttFiles(newAttList);

        this.inputSpecialFk(fruitFeedBackPO);
    }

    /**
     * 消息通知智库管理部门
     * @param fruitPo
     * @param userId
     * @param sendDeptId
     */
    public void sendMessageToOrgMangers(FruitPO fruitPo, Long userId, Long sendDeptId, String receiveTerminal){
        //消息标题
        String title = OrgAccountHelper.getOrgName()
                + (fruitPo.getId() != null ? SystemAssistConstant.systemAssistModule.FRUIT_UPDATE : SystemAssistConstant.systemAssistModule.FRUIT_ADD)
                + "\"" +fruitPo.getName() + "\"" ;
        //新增消息体
        SystemMessageTextPo systemMessageTextPo = messageService.addMessageText(fruitPo.getId(), title, fruitPo.getSummary());
        //智库新增成果通知上级部门
        this.toAddMessageRel(systemMessageTextPo.getId(), userId, sendDeptId,
                SystemAssistConstant.XCB_USER_ID,  SystemAssistConstant.XCB_DEPT_ID, receiveTerminal);
    }

    /**
     * 消息通知智库
     * @param fruitPo
     * @param userId
     * @param sendDeptId
     * @param receiveDeptId
     */
    public void sendMessageToOrg(FruitPO fruitPo, Long userId, Long sendDeptId, Long receiveDeptId, String receiveTerminal){
        //消息标题
        String title = OrgAccountHelper.getOrgName()
                + (fruitPo.getId() != null ? SystemAssistConstant.systemAssistModule.FRUIT_UPDATE : SystemAssistConstant.systemAssistModule.FRUIT_ADD)
                + "\"" +fruitPo.getName() + "\"" ;
        //新增消息体
        SystemMessageTextPo systemMessageTextPo = messageService.addMessageText(fruitPo.getId(), title, fruitPo.getSummary());
        //智库新增成果通知其他智库
        this.toAddMessageRel(systemMessageTextPo.getId(), userId, sendDeptId,null, receiveDeptId, receiveTerminal);
    }

    /**
     * 消息通知专家
     * @param fruitPo
     * @param userId
     * @param receiveUserId
     */
    public void sendMessageToExpert(FruitPO fruitPo, Long userId, Long sendDeptId, Long receiveUserId, String receiveTerminal){
        //消息标题
        String title = OrgAccountHelper.getOrgName()
                + (fruitPo.getId() != null ? SystemAssistConstant.systemAssistModule.FRUIT_UPDATE : SystemAssistConstant.systemAssistModule.FRUIT_ADD)
                + "\"" +fruitPo.getName() + "\"" ;
        //新增消息体
        SystemMessageTextPo systemMessageTextPo = messageService.addMessageText(fruitPo.getId(), title, fruitPo.getSummary());
        //智库新增成果通知对应专家
        this.toAddMessageRel(systemMessageTextPo.getId(), userId, sendDeptId, receiveUserId,null, receiveTerminal);
    }

    //通知信息体
    public void toAddMessageRel(Long messageId, Long sendUserId, Long sendDeptId, Long receiveUserId, Long receiveDeptId, String receiveMessageTerminal){
        messageService.addMessageRel(messageId, sendUserId, sendDeptId, receiveUserId, receiveDeptId,
                receiveMessageTerminal,
                SystemMessageConstant.messageScope.PART,
                SystemMessageConstant.messageClassify.NOTIFICATION,
                SystemMessageConstant.messageType.FRUIT,
                SystemMessageConstant.messageTextState.SENT,
                SystemMessageConstant.messageSendState.SUCCESS,
                SystemAssistConstant.systemAssistTerminal.ORG,
                SystemAssistConstant.systemAssistModule.FRUIT_ADD);
    }

    @Override
    public void orgDelete(Long id) {
        FruitPO fruitPO = fruitRepository.findById(id).orElse(null);
        if(fruitPO != null){
            Long orgId = OrgAccountHelper.getOrgId();
            //如果是机构自己新增的--专家新增对应多个机构  每个机构可以修改作者单位
            if(fruitPO.getOrgId() != null ){
                //逻辑删除，将删除状态改为true---如果成果来源是当前机构，专家新增的数据，机构修改添加作者单位等，不会存储orgId，删除不了
                if(fruitPO.getOrgId().equals(orgId)){
                    fruitPO.setIsDel(true);
                    //将成果里对应的作者和作者单位，状态置为删除---只删除自己机构新增的数据
                    if (!CollectionUtils.isEmpty(fruitPO.getAuthorPOList())) {
                        for (FruitAuthorPO fruitAuthorPO : fruitPO.getAuthorPOList()) {
                            //只删除自己机构新增的数据
                            fruitAuthorPO.setIsDel(true);
                            if (!CollectionUtils.isEmpty(fruitAuthorPO.getOrgPOList())) {
                                for (FruitAuthorOrgPO fruitAuthorOrgPO : fruitAuthorPO.getOrgPOList()) {
                                    fruitAuthorOrgPO.setIsDel(true);
                                }
                            }
                            if(fruitAuthorPO.getOrgUserId() != null){
                                //删除专家和成果的对应关系
                                fruitOrgRelRepository.deleteFruitOrgRelPosByFruitIdAndAuthUserId(id, fruitAuthorPO.getOrgUserId());
                            }
                        }
                    }
                }
                fruitRepository.save(fruitPO);
            }
            //删除通过状态的机构成果
            fruitOrgRelRepository.deleteFruitOrgRelPosByFruitIdAndOrgIdAndStatus(id, orgId, ComConstant.FruitStatus.APPROVED);

            //删除成果关键字--异步
//            wordcloudService.deleteByFruitId(fruitPO.getId());
        }
    }

    /**
     * 查询成果所有内容---可用与导出
     * @param searchDTO
     * @param sortParamsDto
     * @return
     */
    @Override
    public List<FruitPO> readAllOrgFruit(FruitDTO searchDTO, SortParamsDTO sortParamsDto) {
        return this.resultFruitList(searchDTO, sortParamsDto);
    }

    /**
     * 获取所有的成果
     * @return
     */
    public List<FruitPO> resultFruitList(FruitDTO searchDTO, SortParamsDTO sortParamsDto){
        return this.getOrgFruitData(searchDTO, sortParamsDto);
    }

    public List<FruitPO> getOrgFruitData(FruitDTO searchDTO, SortParamsDTO sortParamsDto){
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        // 开启谓语查询条件
        Predicate predicate = getPredicates(qFruitPO, searchDTO);

        return jpaQueryFactory.selectDistinct(qFruitPO)
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(
                        buildOrgIdOrUserIdCondition(qFruitOrgRelPo, qFruitPO, searchDTO, ComConstant.FruitStatus.APPROVED)
                )
                .where(predicate)
                .orderBy(
                        sortParamsDto != null && ("asc").equals(sortParamsDto.getSortDirection())?qFruitPO.pubTime.asc():qFruitPO.pubTime.desc()
                )
                .fetch();
    }


    @Override
    public HashMap<String, Object> getOrgHomePercentData(FruitDTO fruitDTO) {

        HashMap<String, Object> map = new HashMap<>();
        //获取所有的成果数据
        List<ResultHomePercentFruitDTO> friutList = this.getHomePercentFruitList(fruitDTO);

//        map.put("allFruitCount", friutList.size());
//        //获取所有内参
//        map.put("allNcFruitCount",
//                friutList.stream()
//                        .filter(fruitInfoResultDTO ->
//                                fruitInfoResultDTO.getType().equals(ComConstant.FruitType.InternalReferenceReport)
//                        ).count());
//        //获取所有媒体发文
//        map.put("allMtFruitCount",
//                friutList.stream()
//                        .filter(fruitInfoResultDTO ->
//                                fruitInfoResultDTO.getType().equals(ComConstant.FruitType.NewspaperORNetwork)
//                        ).count());
        //所有成果的id
        List<Long> allFruitIdList = friutList.stream().map(ResultHomePercentFruitDTO::getId).collect(Collectors.toList());

        //-----------------------内参-------------进度环----------
        List<ResultHomePercentFruitDTO> ncFriutList = friutList.stream().filter(fruitPO -> fruitPO.getType().equals(ComConstant.FruitType.InternalReferenceReport)) .collect(Collectors.toList());
        //获取所有的内参成果id
        List<Long> ncFruitIdList = ncFriutList.stream().map(ResultHomePercentFruitDTO::getId).collect(Collectors.toList());
        //根据id集合查询所有的批示
        List<ResultPercentPO> ncList = new ArrayList<>();
        QFruitLeaderPO qFruitLeaderPO = QFruitLeaderPO.fruitLeaderPO;
        QSysDict qSysDict = QSysDict.sysDict;
        List<ResultPercentPO> resultPercentPOList = jpaQueryFactory.select(qSysDict.dname, qFruitLeaderPO.inclinationLevel.count())
                .from(qFruitLeaderPO)
                .leftJoin(qSysDict)
                .on(qFruitLeaderPO.inclinationLevel.eq(qSysDict.dvalue)
                        .and(qSysDict.typeKey.eq("InclinationsLevel")))
                .where(qFruitLeaderPO.fruitId.in(ncFruitIdList))
                .groupBy(qFruitLeaderPO.inclinationLevel).fetch().stream()
                .filter(tupler -> !StringUtils.isEmpty(tupler.get(qSysDict.dname))).map(
                        tuple -> {
                            ResultPercentPO resultPercentPO = new ResultPercentPO();
                            resultPercentPO.setResultName(tuple.get(qSysDict.dname));
                            resultPercentPO.setNum(tuple.get(qFruitLeaderPO.inclinationLevel.count()));
                            return resultPercentPO;
                        }
                ).collect(Collectors.toList());


        map.put("ncNum", ncFriutList.size());
        map.put("ncList", resultPercentPOList);

        //-----------------------媒体成果-------------进度环----------
        List<SysDict> pubLevelList = sysdictService.findByTypeKey("PubLevel");
        Map<String, String> pubLevelMap = pubLevelList.stream().collect(Collectors.toMap(SysDict::getDvalue, SysDict::getDname));

        List<ResultHomePercentFruitDTO> bzFruitList = friutList.stream().filter(fruitPO -> fruitPO.getType().equals(ComConstant.FruitType.NewspaperORNetwork)) .collect(Collectors.toList());
        Map<String, Long> bzMap = bzFruitList.stream().filter(fruitPO -> !StringUtils.isEmpty(fruitPO.getPublicationLevel())).collect(Collectors.groupingBy(ResultHomePercentFruitDTO::getPublicationLevel, Collectors.counting()));
        //取出值 拼装list
        List<ResultPercentPO> bzList = bzMap.keySet().stream().map(key -> {
            ResultPercentPO resultPercentPO = new ResultPercentPO(pubLevelMap.get(key), bzMap.get(key).longValue());
            return resultPercentPO;
        }).collect(Collectors.toList());

        map.put("bzNum", bzFruitList.size());
        map.put("bzList", bzList);

        //-----------------------图书出版-------------进度环----------
        List<SysDict> bookTypeList = sysdictService.findByTypeKey("BookType");
        Map<String, String> bookTypeMap = bookTypeList.stream().collect(Collectors.toMap(SysDict::getDvalue, SysDict::getDname));

        List<ResultHomePercentFruitDTO> tsFruitList = friutList.stream().filter(fruitPO -> fruitPO.getType().equals(ComConstant.FruitType.BOOK)) .collect(Collectors.toList());
        Map<String, Long> tsMap = tsFruitList.stream().filter(fruitPO -> !StringUtils.isEmpty(fruitPO.getBookType())).collect(Collectors.groupingBy(ResultHomePercentFruitDTO::getBookType, Collectors.counting()));
        //取出值 拼装list
        List<ResultPercentPO> tsList = tsMap.keySet().stream().map(key -> {
            ResultPercentPO resultPercentPO = new ResultPercentPO(bookTypeMap.get(key), tsMap.get(key).longValue());
            return resultPercentPO;
        }).collect(Collectors.toList());

        map.put("tsNum", tsFruitList.size());
        map.put("tsList", tsList);

        //-----------------------论文-----------------进度环------
        List<SysDict> journalTypeList = sysdictService.findByTypeKey("journalType");
        Map<String, String> journalTypeMap = journalTypeList.stream().collect(Collectors.toMap(SysDict::getDvalue, SysDict::getDname));

        List<ResultHomePercentFruitDTO> lwFruitList = friutList.stream().filter(fruitPO -> fruitPO.getType().equals(ComConstant.FruitType.Paper)).collect(Collectors.toList());
        Map<String, Long> lwMap = lwFruitList.stream().filter(fruitPO -> !StringUtils.isEmpty(fruitPO.getJournalType())).collect(Collectors.groupingBy(ResultHomePercentFruitDTO::getJournalType, Collectors.counting()));

        List<ResultPercentPO> lwList = lwMap.keySet().stream().map(key -> {
            ResultPercentPO resultPercentPO = new ResultPercentPO(journalTypeMap.get(key), lwMap.get(key).longValue());
            return resultPercentPO;
        }).collect(Collectors.toList());

        map.put("lwNum", lwFruitList.size());
        map.put("lwList", lwList);

        //-----------------------报告------------------进度环-----
        List<SysDict> reportTypeList = sysdictService.findByTypeKey("reportType");
        Map<String, String> reportTypeMap = reportTypeList.stream().collect(Collectors.toMap(SysDict::getDvalue, SysDict::getDname));

        List<ResultHomePercentFruitDTO> bgFriutList = friutList.stream().filter(fruitPO -> fruitPO.getType().equals(ComConstant.FruitType.REPORT)).collect(Collectors.toList());
//        Map<String, Long> bgMap = bgFriutList.stream().filter(fruitPO -> !StringUtils.isEmpty(fruitPO.getReportType())).collect(Collectors.groupingBy(FruitPO::getReportType, Collectors.counting()));
//
//        List<ResultPercentPO> bgList = bgMap.keySet().stream().map(key -> {
//            ResultPercentPO resultPercentPO = new ResultPercentPO(reportTypeMap.get(key), bgMap.get(key).longValue());
//            return resultPercentPO;
//        }).collect(Collectors.toList());

        map.put("bgNum", bgFriutList.size());
//        map.put("bgList", bgList);
        map.put("bgList", null);

        //-----------------------活动参与---------------进度环--------
//        List<SysDict> clientLevelList = sysdictService.findByTypeKey("clientLevel");
//        Map<String, String> clientLevelMap = clientLevelList.stream().collect(Collectors.toMap(SysDict::getDvalue, SysDict::getDname));
        Map<String, String> activityMap = ComConstant.descValueMapCons.get("ProductionActivityType");

        List<ResultHomePercentFruitDTO> zcFriutList = friutList.stream().filter(fruitPO -> fruitPO.getType().equals(ComConstant.FruitType.PolicyAdvice)).collect(Collectors.toList());
        Map<String, Long> zcMap = zcFriutList.stream().filter(fruitPO -> !StringUtils.isEmpty(fruitPO.getActivityProdType())).collect(Collectors.groupingBy(ResultHomePercentFruitDTO::getActivityProdType, Collectors.counting()));

        List<ResultPercentPO> zcList = zcMap.keySet().stream().map(key -> {
            ResultPercentPO resultPercentPO = new ResultPercentPO(activityMap.get(key), zcMap.get(key).longValue());
            return resultPercentPO;
        }).collect(Collectors.toList());

        map.put("zcNum", zcFriutList.size());
        map.put("zcList", zcList);

        //-----------------------荣誉---------------进度环--------
        List<SysDict> awardLevelList = sysdictService.findByTypeKey("AwardLevel");
        Map<String, String> awardLevelMap = awardLevelList.stream().collect(Collectors.toMap(SysDict::getDvalue, SysDict::getDname));

        List<ResultHomePercentFruitDTO> ryFruitList = friutList.stream().filter(fruitPO -> fruitPO.getType().equals(ComConstant.FruitType.PRICE)).collect(Collectors.toList());
        Map<String, Long> ryMap = ryFruitList.stream().filter(fruitPO -> !StringUtils.isEmpty(fruitPO.getAwardsLevel())).collect(Collectors.groupingBy(ResultHomePercentFruitDTO::getAwardsLevel, Collectors.counting()));

        List<ResultPercentPO> ryList = ryMap.keySet().stream().map(key -> {
            ResultPercentPO resultPercentPO = new ResultPercentPO(awardLevelMap.get(key), ryMap.get(key).longValue());
            return resultPercentPO;
        }).collect(Collectors.toList());

        map.put("ryNum", ryFruitList.size());
        map.put("ryList", ryList);

        //-----------------------项目---------------进度环--------
        List<SysDict> clientLevelList = sysdictService.findByTypeKey("ClientLevel");
        Map<String, String> clientLevelMap = clientLevelList.stream().collect(Collectors.toMap(SysDict::getDvalue, SysDict::getDname));

        List<ResultHomePercentFruitDTO> xmFruitList = friutList.stream().filter(fruitPO -> fruitPO.getType().equals(ComConstant.FruitType.PROJECT)).collect(Collectors.toList());
        Map<String, Long> xmMap = xmFruitList.stream().filter(fruitPO -> !StringUtils.isEmpty(fruitPO.getClientLevel())).collect(Collectors.groupingBy(ResultHomePercentFruitDTO::getClientLevel, Collectors.counting()));

        List<ResultPercentPO> xmList = xmMap.keySet().stream().map(key -> {
            ResultPercentPO resultPercentPO = new ResultPercentPO(clientLevelMap.get(key), xmMap.get(key));
            return resultPercentPO;
        }).collect(Collectors.toList());

        map.put("xmNum", xmFruitList.size());
        map.put("xmList", xmList);


        //-----------------------成果按年份查询-----成果按年份查询------图表------------
        Map<String, List<ResultLinePO>> fruitsYear = this.getFruitsGroupByYear(fruitDTO);
        Map<String, List<ResultLinePO>> fruitsExpertYear = this.getFruitsExpertGroupByYear(fruitDTO);
        //咨政内参
//        List<ResultLinePO> ncYearList = this.getProdTypeListByYear(ncFriutList);
        List<ResultLinePO> ncYearList = fruitsYear.get(ComConstant.FruitType.InternalReferenceReport);
//        List<ResultLinePO> ncExpertYearList = this.getProdTypeExpertListByYear(ncFriutList);
        List<ResultLinePO> ncExpertYearList = fruitsExpertYear.get(ComConstant.FruitType.InternalReferenceReport);
        //学术论文
//        List<ResultLinePO> lwYearList = this.getProdTypeListByYear(lwFruitList);
        List<ResultLinePO> lwYearList = fruitsYear.get(ComConstant.FruitType.Paper);
//        List<ResultLinePO> lwExpertYearList = this.getProdTypeExpertListByYear(lwFruitList);
        List<ResultLinePO> lwExpertYearList = fruitsExpertYear.get(ComConstant.FruitType.Paper);
        //研究报告
//        List<ResultLinePO> bgYearList = this.getProdTypeListByYear(bgFriutList);
        List<ResultLinePO> bgYearList = fruitsYear.get(ComConstant.FruitType.REPORT);
//        List<ResultLinePO> bgExpertYearList = this.getProdTypeExpertListByYear(bgFriutList);
        List<ResultLinePO> bgExpertYearList = fruitsExpertYear.get(ComConstant.FruitType.REPORT);
        //图书出版
//        List<ResultLinePO> tsYearList = this.getProdTypeListByYear(tsFruitList);
        List<ResultLinePO> tsYearList = fruitsYear.get(ComConstant.FruitType.BOOK);
//        List<ResultLinePO> tsExpertYearList = this.getProdTypeExpertListByYear(tsFruitList);
        List<ResultLinePO> tsExpertYearList = fruitsExpertYear.get(ComConstant.FruitType.BOOK);
        //活动参与
//        List<ResultLinePO> zcYearList = this.getProdTypeListByYear(zcFriutList);
        List<ResultLinePO> zcYearList = fruitsYear.get(ComConstant.FruitType.PolicyAdvice);
//        List<ResultLinePO> zcExpertYearList = this.getProdTypeExpertListByYear(zcFriutList);
        List<ResultLinePO> zcExpertYearList = fruitsExpertYear.get(ComConstant.FruitType.PolicyAdvice);
        //媒体成果
//        List<ResultLinePO> bzYearList = this.getProdTypeListByYear(bzFruitList);
        List<ResultLinePO> bzYearList = fruitsYear.get(ComConstant.FruitType.NewspaperORNetwork);
//        List<ResultLinePO> bzExpertYearList = this.getProdTypeExpertListByYear(bzFruitList);
        List<ResultLinePO> bzExpertYearList = fruitsExpertYear.get(ComConstant.FruitType.NewspaperORNetwork);

        //荣誉
        List<ResultLinePO> ryYearList = fruitsYear.get(ComConstant.FruitType.PRICE);
        List<ResultLinePO> ryExpertYearList = fruitsExpertYear.get(ComConstant.FruitType.PRICE);
        //承担项目
        List<ResultLinePO> xmYearList = fruitsYear.get(ComConstant.FruitType.PROJECT);
        List<ResultLinePO> xmExpertYearList = fruitsExpertYear.get(ComConstant.FruitType.PROJECT);

        Map<String, List<ResultLinePO>> fruitYearList= new HashMap<>();
        fruitYearList.put("ncYearList", ncYearList);
        fruitYearList.put("lwYearList", lwYearList);
        fruitYearList.put("bgYearList", bgYearList);
        fruitYearList.put("tsYearList", tsYearList);
        fruitYearList.put("zcYearList", zcYearList);
        fruitYearList.put("bzYearList", bzYearList);
        fruitYearList.put("ryYearList", ryYearList);
        fruitYearList.put("xmYearList", xmYearList);

        map.put("fruitYearList", fruitYearList);

        Map<String, List<ResultLinePO>> expertYearList= new HashMap<>();
        expertYearList.put("ncExpertYearList", ncExpertYearList);
        expertYearList.put("lwExpertYearList", lwExpertYearList);
        expertYearList.put("bgExpertYearList", bgExpertYearList);
        expertYearList.put("tsExpertYearList", tsExpertYearList);
        expertYearList.put("zcExpertYearList", zcExpertYearList);
        expertYearList.put("bzExpertYearList", bzExpertYearList);
        expertYearList.put("ryExpertYearList", ryExpertYearList);
        expertYearList.put("xmExpertYearList", xmExpertYearList);

        map.put("expertYearList", expertYearList);

        //--------------------国际级---国家级---省部级---厅局级----成果数-----------------------

//        Map<String, Integer> fruitLevelMap = new HashMap<>();
        //---------------------------- 咨政内参-------------------------------------------
        //----内参报送与批示级别比较------
//        Map<String, Long> ncBsfruitNumMap = this.getBsAndPsLevelFruitNum(ncFruitIdList);
//        //国家级
//        fruitLevelMap.put("nationNum", validateValue(ncBsfruitNumMap.get("1")) + validateValue(ncBsfruitNumMap.get("2")));
//        //省部级
//        fruitLevelMap.put("provinceNum", validateValue(ncBsfruitNumMap.get("3")) + validateValue(ncBsfruitNumMap.get("4")));
//        //厅局级
//        fruitLevelMap.put("bureauNum", validateValue(ncBsfruitNumMap.get("5")) + validateValue(ncBsfruitNumMap.get("6")));

        //---------------------------- 学术论文 研究报告 图书出版 媒体成果-------------------------
//        List<Long> someFruitIdList = friutList.stream()
//                .filter(fruitPO ->  !fruitPO.getType().equals(ComConstant.FruitType.InternalReferenceReport) &&
//                        !fruitPO.getType().equals(ComConstant.FruitType.PolicyAdvice) &&
//                        !fruitPO.getType().equals(ComConstant.FruitType.PRICE) )
//                .map(ResultHomePercentFruitDTO::getId).collect(Collectors.toList());
//        //批示中最小的值的批示并分组
//        Map<String, Long> fruitNumMap = this.getPsLevelFruitNum(someFruitIdList);
//        //国家级
//        fruitLevelMap.put("nationNum", fruitLevelMap.get("nationNum") + validateValue(fruitNumMap.get("1")) + validateValue(fruitNumMap.get("2")));
//        //省部级
//        fruitLevelMap.put("provinceNum", fruitLevelMap.get("provinceNum") + validateValue(fruitNumMap.get("3")) + validateValue(fruitNumMap.get("4")));
//        //厅局级
//        fruitLevelMap.put("bureauNum", fruitLevelMap.get("bureauNum") + validateValue(fruitNumMap.get("5")) + validateValue(fruitNumMap.get("6")));
//
//        //----------------------------活动参与---荣誉信息--------------------------
//        //级别分组的数据
//        Map<String, Long> twoFruitMap = friutList.stream()
//                .filter(fruitPO ->  fruitPO.getType().equals(ComConstant.FruitType.PolicyAdvice) || fruitPO.getType().equals(ComConstant.FruitType.PRICE))
//                .filter(fruitPO -> !StringUtils.isEmpty(fruitPO.getAwardsLevel()))
//                .collect(Collectors.groupingBy(o -> o.getAwardsLevel(), Collectors.counting()));
//        //国际级
//        fruitLevelMap.put("internationalNum", validateValue(twoFruitMap.get("1")));
//        //国家级
//        fruitLevelMap.put("nationNum", fruitLevelMap.get("nationNum") + validateValue(twoFruitMap.get("2")));
//        //省部级
//        fruitLevelMap.put("provinceNum", fruitLevelMap.get("provinceNum") + validateValue(twoFruitMap.get("3")));
//        //厅局级
//        fruitLevelMap.put("bureauNum", fruitLevelMap.get("bureauNum") + validateValue(twoFruitMap.get("4")));
//
//        map.put("fruitTypeLevelNum", fruitLevelMap);

        // ----------------------------------专家活跃度排名 --所有类型加在一起的排名---------------------------
//        QFruitPO qFruitPO = QFruitPO.fruitPO;
//        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
//        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
//        //获取专家的成果总数排名 取10的专家id
//        List<Long> expertListId = new ArrayList<>();
//        List<String> expertListName = new ArrayList<>();
//
//        jpaQueryFactory.select(
//                qFruitAuthorPO.orgUserId,
//                qFruitAuthorPO.author,
//                qFruitAuthorPO.fruitId.count()
//        )
//                .from(qFruitOrgRelPo)
//                .leftJoin(qFruitPO).on(qFruitOrgRelPo.fruitId.eq(qFruitPO.id)
//                .and(qFruitOrgRelPo.orgId.eq(fruitDTO.getOrgId())))
//                .leftJoin(qFruitAuthorPO).on(qFruitPO.id.eq(qFruitAuthorPO.fruitId))
//                .where(qFruitAuthorPO.orgUserId.isNotNull()
//                        .and(qFruitPO.id.isNotNull().and(qFruitPO.isDel.isFalse()))
//                ).groupBy(qFruitAuthorPO.orgUserId).orderBy(qFruitAuthorPO.fruitId.count().desc()).limit(10)
//                .fetch().stream()
//                .forEach(tuple -> {
//                    expertListId.add( tuple.get(qFruitAuthorPO.orgUserId));
//                    expertListName.add( tuple.get(qFruitAuthorPO.author));
//                });
//        //分组查询
//        List<ResultExpertDTO> resultExpertList = jpaQueryFactory.select(
//                Projections.constructor(ResultExpertDTO.class,
//                        qFruitAuthorPO.orgUserId.as("userId"),
//                        qSysDict.dname.as("typeName"),
//                        qFruitAuthorPO.author.as("author"),
//                        qFruitPO.id.count().as("num")
//                )
//        )
//                .from(qSysDict)
//                .leftJoin(qFruitPO).on(qSysDict.dvalue.eq(qFruitPO.type))
//                .leftJoin(qFruitAuthorPO).on(qFruitAuthorPO.fruitId.eq(qFruitPO.id))
//                .where(qSysDict.typeKey.eq("FruitType").and(qFruitAuthorPO.orgUserId.in(expertListId)))
//                .groupBy(qSysDict.dname, qFruitAuthorPO.orgUserId)
//                .fetch();
//        //所有成果类型
//        List<String> fruitTypeList = jpaQueryFactory.select(qSysDict.dname)
//                .from(qSysDict).where(qSysDict.typeKey.eq("FruitType")
//                        .and(qSysDict.dvalue.ne("1"))
//                        .and(qSysDict.dvalue.ne("9"))
//                ).orderBy(qSysDict.createTime.asc()).fetch();
//        //重新整理数据 拼接处理
//        List<ResultExpertDTO> expertRankList = new ArrayList<>();
//        fruitTypeList.forEach(fruitName->{
//            List<Integer> countList = new ArrayList<>();
//            expertListId.forEach(expertId->{
//                //判断专家id和成果名称都相同时
//                List<ResultExpertDTO>  filterList = resultExpertList.stream()
//                        .filter(resultExpertDTO ->
//                                resultExpertDTO.typeName.equals(fruitName)
//                                        && (resultExpertDTO.userId == expertId)
//                        ).collect(Collectors.toList());
//                countList.add(!CollectionUtils.isEmpty(filterList) ? filterList.get(0).getNum().intValue() : 0);
//            });
//            ResultExpertDTO resultExpertDTO = new ResultExpertDTO(fruitName, countList);
//            expertRankList.add(resultExpertDTO);
//         });
//        map.put("expertRankingFruitList", expertRankList);
//        map.put("expertRankingNameList", expertListName);

        // ----------------------------------专家活跃度排名 --各种类型分开的排名---------------------------
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;

        Map<String, List<ResultExpertDTO>> expertMap = new HashMap<>();
        jpaQueryFactory.select(
                qSysDict.dname,
                qFruitAuthorPO.author,
                qFruitAuthorPO.fruitId.count()
        )
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(
                buildOrgIdOrUserIdCondition(qFruitOrgRelPo, qFruitPO, fruitDTO, ComConstant.FruitStatus.APPROVED)
        )
                .leftJoin(qFruitAuthorPO).on(qFruitPO.id.eq(qFruitAuthorPO.fruitId))
                .leftJoin(qSysDict).on(qSysDict.typeKey.eq("FruitType").and(qSysDict.dvalue.eq(qFruitPO.type)))
                .where(qFruitAuthorPO.orgUserId.isNotNull()
                        .and(qFruitPO.id.isNotNull()
                                .and(qFruitPO.isDel.isFalse())
                                .and(qFruitPO.isPublic.eq("0"))
                        ).and(qSysDict.dvalue.isNotNull())
                ).groupBy(qSysDict.dname, qFruitAuthorPO.author)
                .orderBy(qSysDict.dname.asc())
                .orderBy(qFruitAuthorPO.fruitId.count().desc())
                .fetch()
                .forEach(tuple -> {
                    if(CollectionUtils.isEmpty(expertMap.get(tuple.get(qSysDict.dname))) || expertMap.get(tuple.get(qSysDict.dname)).size() < 10){
                        ResultExpertDTO resultExpertDTO = new ResultExpertDTO(tuple.get(qFruitAuthorPO.author), tuple.get(qFruitAuthorPO.fruitId.count()));
                        if(CollectionUtils.isEmpty(expertMap.get(tuple.get(qSysDict.dname)))){
                            List<ResultExpertDTO> resultExpertDTOList = new ArrayList<>();
                            resultExpertDTOList.add(resultExpertDTO);
                            expertMap.put(tuple.get(qSysDict.dname), resultExpertDTOList);
                        }else{
                            expertMap.get(tuple.get(qSysDict.dname)).add(resultExpertDTO);
                        }

                    }
                });
        List<ResultExpertDTO> res = new ArrayList<>();
        expertMap.forEach((key, value) -> {
            ResultExpertDTO resultExpertDTO = new ResultExpertDTO();
            resultExpertDTO.setTypeName(key);
            resultExpertDTO.setExpertResult(value);
            res.add(resultExpertDTO);
        });
        map.put("expertRankingList", res);
        return map;
    }

    /**
     * 机构端获取百分比  图表成果元数据
     * @param fruitDTO
     * @return
     */
    public List<ResultHomePercentFruitDTO> getHomePercentFruitList(FruitDTO fruitDTO){
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;

        List<ResultHomePercentFruitDTO> resultList = jpaQueryFactory.select(
                Projections.constructor(ResultHomePercentFruitDTO.class,
                        qFruitPO.id,
                        qFruitPO.type,
                        qFruitPO.publicationLevel,
                        qFruitPO.bookType,
                        qFruitPO.journalType,
                        qFruitPO.activityProdType,
                        qFruitPO.awardsLevel,
                        qFruitPO.clientLevel
                ))
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(
                    buildOrgIdOrUserIdCondition(qFruitOrgRelPo, qFruitPO, fruitDTO, ComConstant.FruitStatus.APPROVED)
                )
                .where(qFruitPO.id.isNotNull().and(qFruitPO.isDel.isFalse()))
                .fetch();

        return resultList;
    }


    public List<ResultLinePO> getProdTypeListByYear(List<FruitPO> friutList, long orgId){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        //根据年份分组
        Map<Integer, Long> yearMap = friutList.stream().filter(fruitPO -> !StringUtils.isEmpty(fruitPO.getPubTime()))
                .collect(Collectors.groupingBy(o -> Integer.parseInt(sdf.format(o.getPubTime())), Collectors.counting()));
        //按年份排序
        Map<Integer, Long> resultMap = yearMap.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                        (oleValue, newValue) -> oleValue, LinkedHashMap::new));

        //取出值 拼装list
        List<ResultLinePO> resultFruitList = resultMap.keySet().stream().map(key -> {
            ResultLinePO resultLinePO = new ResultLinePO(key+"", resultMap.get(key).longValue());
            return resultLinePO;
        }).collect(Collectors.toList());

        return resultFruitList;
    }

    /**
     * 成果按年统计---首页图表
     * @return
     */
    public Map<String, List<ResultLinePO>> getFruitsGroupByYear(FruitDTO fruitDTO){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        Map<String, List<ResultLinePO>> map = new HashMap<>();
        //建立模版
        StringTemplate dataeExpr = Expressions.stringTemplate("DATE_FORMAT({0},'%Y')", qFruitPO.pubTime);
        jpaQueryFactory.select(qFruitPO.type, qFruitPO.type.count(), dataeExpr)
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO)
                .on(qFruitPO.id.eq(qFruitOrgRelPo.fruitId)
                        .and(qFruitPO.isDel.eq(false))
                        .and(qFruitPO.pubTime.isNotNull())
                        .and(qFruitOrgRelPo.orgId.in(fruitDTO.getOrgIdList())))
                .groupBy(qFruitPO.type, dataeExpr)
                .having(qFruitPO.type.isNotNull()).fetch().stream()
                .forEach(
                        tuple -> {
                            String ftype = tuple.get(qFruitPO.type);
                            List<ResultLinePO> results = map.get(ftype);
                            if(CollectionUtils.isEmpty(results)){
                                results = new ArrayList<>();
                            }
                            //清洗整理结果集
                            ResultLinePO resultLinePO = new ResultLinePO();
                            resultLinePO.setYearName(tuple.get(dataeExpr));
                            resultLinePO.setNum(tuple.get(qFruitPO.type.count()));

                            results.add(resultLinePO);
                            map.put(ftype, results);
                        }
                );
        return map;
    }


    public List<ResultLinePO> getProdTypeExpertListByYear(List<FruitPO> friutList){
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
//        //根据年份分组
//        Map<Integer, List<FruitPO>> yearMap = friutList.stream().filter(fruitPO -> !StringUtils.isEmpty(fruitPO.getPubTime()))
//                .collect(Collectors.groupingBy(o -> Integer.parseInt(sdf.format(o.getPubTime()))));
//
//        //按年份排序
//        Map<Integer, List<FruitPO>> resultMap = yearMap.entrySet().stream() .sorted(Map.Entry.comparingByKey())
//                                                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
//                                                        (oleValue, newValue) -> oleValue, LinkedHashMap::new));
//
//        List<ResultLinePO> resultFruitList = new ArrayList<>();
//       //遍历循环 取每一年的专家数量
//        resultMap.forEach((yearName, fList) -> {
//            List<FruitAuthorPO> fruitAuthorPOList =  new ArrayList<>();
//            fList.stream().filter(fruitPO -> !CollectionUtils.isEmpty(fruitPO.getAuthorPOList())).forEach(fruitPo->{
//                fruitPo.getAuthorPOList().forEach(fruitAuthorPO -> fruitAuthorPOList.add(fruitAuthorPO));
//            });
//            //拼接对象
//            ResultLinePO resultLinePO = new ResultLinePO();
//            resultLinePO.setYearName(yearName + "");
//            //去重
//            Integer num = fruitAuthorPOList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
//                            () -> new TreeSet<>(Comparator.comparing(o -> o.getAuthor()))), ArrayList::new)).size();
//            resultLinePO.setNum(num.longValue());
//            resultFruitList.add(resultLinePO);
//        });

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        //获取所有的成果id
        List<Long> fruitIdList = friutList.stream().map(FruitPO::getId).collect(Collectors.toList());
        //根据id集合查询所有的作者
        List<ResultPercentPO> ncList = new ArrayList<>();
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        //建立模版
        StringTemplate dataeExpr = Expressions.stringTemplate("DATE_FORMAT({0},'%Y')", qFruitPO.pubTime);
        List<ResultLinePO> resultPercentPOList = jpaQueryFactory.select(qFruitAuthorPO.author.countDistinct(), dataeExpr)
                .from(qFruitPO)
                .leftJoin(qFruitAuthorPO).on(qFruitPO.id.eq(qFruitAuthorPO.fruitId).and(qFruitAuthorPO.author.isNotEmpty()))
                .where(qFruitPO.id.in(fruitIdList).and(qFruitPO.pubTime.isNotNull())).groupBy(dataeExpr)
                .fetch().stream().map(
                        tuple -> {
                            ResultLinePO resultLinePO = new ResultLinePO();
                            resultLinePO.setNum(tuple.get(qFruitAuthorPO.author.countDistinct()));
                            resultLinePO.setYearName(tuple.get(dataeExpr));
                            return resultLinePO;
                        }
                ).collect(Collectors.toList());

        return resultPercentPOList;
    }

    /**
     * 专家参与按年统计---首页图表
     * @return
     */
    public Map<String, List<ResultLinePO>> getFruitsExpertGroupByYear(FruitDTO fruitDTO){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        Map<String, List<ResultLinePO>> map = new HashMap<>();
        //建立模版
        StringTemplate dataeExpr = Expressions.stringTemplate("DATE_FORMAT({0},'%Y')", qFruitPO.pubTime);
        jpaQueryFactory.select(qFruitPO.type, qFruitAuthorPO.author.count(), dataeExpr)
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(qFruitPO.id.eq(qFruitOrgRelPo.fruitId)
                .and(qFruitPO.isDel.eq(false))
                .and(qFruitPO.pubTime.isNotNull())
                .and(qFruitOrgRelPo.orgId.in(fruitDTO.getOrgIdList())))
                .leftJoin(qFruitAuthorPO).on(qFruitPO.id.eq(qFruitAuthorPO.fruitId)
                .and(qFruitAuthorPO.isDel.eq(false)))
                .groupBy(qFruitPO.type, dataeExpr)
                .having(qFruitPO.type.isNotNull()).fetch().stream()
                .forEach(
                        tuple -> {
                            String ftype = tuple.get(qFruitPO.type);
                            List<ResultLinePO> results = map.get(ftype);
                            if(CollectionUtils.isEmpty(results)){
                                results = new ArrayList<>();
                            }
                            //清洗整理结果集
                            ResultLinePO resultLinePO = new ResultLinePO();
                            resultLinePO.setYearName(tuple.get(dataeExpr));
                            resultLinePO.setNum(tuple.get(qFruitAuthorPO.author.count()));

                            results.add(resultLinePO);
                            map.put(ftype, results);
                        }
                );
        return map;
    }

    @Override
    public long readAllFruitByTopicId(Long id) {
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        long count = jpaQueryFactory.selectFrom(qFruitPO).where(qFruitPO.topicId.eq(String.valueOf(id)).and(qFruitPO.isDel.isFalse())).fetchCount();
        return count;
    }

    @Override
    public List<FruitPO> readAllFruitByProjectId(Long projectId) {
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        List<FruitPO> fruitPOList = jpaQueryFactory.selectFrom(qFruitPO).where(qFruitPO.isDel.isFalse().and(qFruitPO.topicId.eq(String.valueOf(projectId)))).fetch();
        return fruitPOList;
    }

    //-------------------------------------------------------------------------------------------------------------------
    //----------------------------------------------------专家端----------------------------------------------------------
    //-------------------------------------------------------------------------------------------------------------------

    /**
     * 专家端新增成果
     * @param fruitDTO
     */
    @Override
    public void expertCreate(FruitDTO fruitDTO) {
        Long userId = OrgAccountHelper.getUserId();
        String userName = orgUserService.readOneById(userId).getRealName();
        //判断当前添加成果的专家是否存在于 新增成果里面的专家--存在 设置id 方便后面新增关联关系
        List<FruitAuthorPO> fruitAuthorPOList = fruitDTO.getAuthorPOList();
        //查询系统专家库--正式+临时
        List<ExpertSearchDto>  allExpertList = tempExpertService.findAllExpert(true);
        if(!CollectionUtils.isEmpty(fruitAuthorPOList)){
            fruitAuthorPOList.forEach(authorPO -> {
                //判断是否是汉字  去除空格  英文跳过
                String author = CommonUtil.replaceBlankOfName(authorPO.getAuthor());
                Long authorId = allExpertList.stream().filter(expertSearchDto -> author.equals(expertSearchDto.getAuthor())).map(ExpertSearchDto::getOrgUserId).findFirst().orElse(null);
                authorPO.setOrgUserId(authorId);
//                if(userName.equals(author)){
//                    authorPO.setOrgUserId(userId);
//                }
            });
        }

        FruitPO fruitPO;
        // -------------新增-------------
        if(fruitDTO.getId() == null){
            fruitDTO.setUserId(userId);
            fruitDTO.setUserName(userName);
            //保存成果
            fruitPO = fruitRepository.save(fruitMapper.dto2po(fruitDTO));
            //更新成果的初始id
            fruitPO.setInitFruitId(fruitPO.getId());
            fruitRepository.save(fruitPO);
        }else{
            // -------------修改-------------
            //新版本--第一版不是当前专家新增的  新增新版本数据
//            if(fruitDTO.isEdit() && !userId.equals(fruitDTO.getUserId())){
//                fruitPO = this.expertCreateNewFruit(fruitDTO, userId);
//            }else{
                fruitPO = fruitRepository.save(fruitMapper.dto2po(fruitDTO));
//            }
            //先删除关键字
//            wordcloudService.deleteByFruitId(fruitPO.getId());
        }
        //专家给机构新增成果关系
        this.expertCreateFruitOrgRelation(fruitPO);
        //专家给专家新增成果关系
        this.expertCreatFruitExpertRelation(fruitPO);

        //设置成果关键字--异步
//        wordcloudService.create(fruitPO.getId());
    }


    /**
     * 专家新增新版本成果
     * @param fruitDTO
     */
    public FruitPO expertCreateNewFruit(FruitDTO fruitDTO, Long userId){
        FruitPO newFruitPO = null;
        try {
            //---更新基础信息
            newFruitPO = this.createNewFruit(fruitDTO, null, userId);
            //更新关联关系的parentId
            QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
            FruitOrgRelPo fruitOrgRelPo = jpaQueryFactory.selectFrom(qFruitOrgRelPo)
                    .where(qFruitOrgRelPo.authUserId.eq(userId).and(qFruitOrgRelPo.fruitId.eq(fruitDTO.getId())))
                    .fetchOne();
            if(fruitOrgRelPo != null){
                fruitOrgRelPo.setFruitId(newFruitPO.getId());
                fruitOrgRelRepository.save(fruitOrgRelPo);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return newFruitPO;
    }

    /**
     * 专家给专家添加成果关联关系--需要专家审核（类似专家认领）
     */
    public void expertCreatFruitExpertRelation(FruitPO fruitPO){

        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        long count = jpaQueryFactory.selectFrom(qFruitOrgRelPo).where(qFruitOrgRelPo.authUserId.eq(OrgAccountHelper.getUserId()).and(qFruitOrgRelPo.fruitId.eq(fruitPO.getId()))).fetchCount();
        if (count == 0) {
            this.createFruitOrgOrExpertRel(null, OrgAccountHelper.getUserId(), fruitPO.getId(), fruitPO.getInitFruitId(), ComConstant.FruitStatus.APPROVED);
        }

//        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
//        //查询系统专家库--正式+临时
//        List<ExpertSearchDto>  allExpertList = tempExpertService.findAllExpert(true);
//        for (FruitAuthorPO fruitAuthorPO : fruitPO.getAuthorPOList()) {
//            //fruitAuthorPO里面只有authorName  没有orgUserId  需要去匹配
//            String fruitAuthorName = fruitAuthorPO.getAuthor();
//            if(!StringUtils.isEmpty(fruitAuthorName)){
//                for (ExpertSearchDto expertEntity : allExpertList) {
//                    //如果能匹配上 就添加关联关系（重名专家--自己审核认领）
//                    if(fruitAuthorName.equals(expertEntity.getAuthor())){
//                        //新增专家与成果的关系--不需要填写orgId, 机构查询方便过滤
//                        String status = ComConstant.FruitStatus.WATICHECK;
//                        //自己新增的 不需要审核
//                        if(expertEntity.getOrgUserId().equals(fruitPO.getUserId())){
//                            status = ComConstant.FruitStatus.APPROVED;
//                        }
//                        //判断专家是否已经添加过对应关系
//                        long fruitCount = jpaQueryFactory.selectFrom(qFruitOrgRelPo).where(qFruitOrgRelPo.authUserId.eq(expertEntity.getOrgUserId()).and(qFruitOrgRelPo.initFruitId.eq(fruitPO.getInitFruitId()))).fetchCount();
//                        if(fruitCount == 0) {
//                            this.createFruitOrgOrExpertRel(null, expertEntity.getOrgUserId(), fruitPO.getId(), fruitPO.getInitFruitId(), status);
//                            //消息通知
//                            this.sendMessageToExpert(fruitPO, OrgAccountHelper.getUserId(), null, expertEntity.getOrgUserId(),
//                                    SystemAssistConstant.systemAssistTerminal.EXPERT);
//                        }
//                    }else{
//                        //TODO 匹配不上是否需要添加临时专家关系（专家是否有权限新增，数据是否会冗余）
//
//                    }
//                }
//            }
//        }
    }

    /**
     * 专家新增成果与机构匹配关系
     * @param fruitPO
     */
    public void expertCreateFruitOrgRelation(FruitPO fruitPO){
        //查询专家是哪一个部门的
        QOrgUserRelPo qOrgUserRelPo = QOrgUserRelPo.orgUserRelPo;
        jpaQueryFactory.selectFrom(qOrgUserRelPo)
                .where(qOrgUserRelPo.user.id.eq(fruitPO.getUserId()).and(qOrgUserRelPo.expert.eq(true))).fetch().forEach(orgUserRelPo -> {
            Long deptId = orgUserRelPo.getOrg().getId();

            QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
            long count = jpaQueryFactory.selectFrom(qFruitOrgRelPo).where(qFruitOrgRelPo.orgId.eq(deptId).and(qFruitOrgRelPo.fruitId.eq(fruitPO.getId()))).fetchCount();
            if (count == 0) {
                //添加机构与成果的对应关系
                this.createFruitOrgOrExpertRel(deptId, null, fruitPO.getId(), fruitPO.getInitFruitId(), ComConstant.FruitStatus.WATICHECK);
            }
        });


//        List<String> addOrgNames = new ArrayList<>();
//        //获取提交成果的机构单位名称
//        fruitPO.getAuthorPOList().forEach(authorPO-> {
//            authorPO.getOrgPOList().forEach(orgPo->{
//                addOrgNames.add(orgPo.getName());
//            });
//        });
//
//        //专家所属的全职机构
//        List<String> orgUserRelOrgNames = new ArrayList<>();
//        QOrgUserRelPo qOrgUserRelPo = QOrgUserRelPo.orgUserRelPo;
//        jpaQueryFactory.selectFrom(qOrgUserRelPo)
//                .where(qOrgUserRelPo.user.id.eq(fruitPO.getUserId()).and(qOrgUserRelPo.expert.eq(true))
//                        .and(qOrgUserRelPo.fullTime.eq(true))
//                ).fetch().forEach(orgUserRelPo -> {
//            orgUserRelOrgNames.add(orgUserRelPo.getOrg().getNameZh());
//        });
//        //取机构名称的list-去重取并集
//        List<String> orgNames = Stream.of(addOrgNames, orgUserRelOrgNames).flatMap(Collection::stream).distinct().collect(Collectors.toList());
//
//        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
//        if(!CollectionUtils.isEmpty(orgNames)){
//            //获取所有机构关键词map
//            Map<OrgPo, List<OrgKeywordPo>> orgKeywordsMap = this.getAllOrgKeyWords();
//            orgNames.forEach(orgName -> {
//                Long sendOrgId = this.matchKeyWordsAndGetOrgId(orgKeywordsMap, orgName);
//                //如果匹配上,那就保存机构与成果的对应关系
//                if (sendOrgId != null) {
//                    //判断是否已经存在--因全职机构名称和专家填写的名称 可能不一样但却是同一个机构（上面的去重不了）
//                    long count = jpaQueryFactory.selectFrom(qFruitOrgRelPo).where(qFruitOrgRelPo.orgId.eq(sendOrgId).and(qFruitOrgRelPo.fruitId.eq(fruitPO.getInitFruitId()))).fetchCount();
//                    if (count == 0) {
//                        //添加机构与成果的对应关系
//                        this.createFruitOrgOrExpertRel(sendOrgId, null, fruitPO.getId(), fruitPO.getInitFruitId(), ComConstant.FruitStatus.WATICHECK);
//                        //消息通知机构
//                        this.sendMessageToOrg(fruitPO, OrgAccountHelper.getUserId(), null, sendOrgId,
//                                SystemAssistConstant.systemAssistTerminal.ORG);
//                    }
//                }
//            });
//        }
    }


    @Override
    public HashMap<String, Object> getExpertHomePercentData(FruitDTO fruitDTO) {

        HashMap<String, Object> map = new HashMap<>();
        Long orgUserId = fruitDTO.getOrgUserId();
        // 咨政内参
        int ncNum = this.getExpertFruitTypeNum(fruitDTO, ComConstant.FruitType.InternalReferenceReport);
        List<ResultPercentPO> ncList = fruitRepository.getExpertDetailPsData(orgUserId, ComConstant.FruitType.InternalReferenceReport);
        map.put("ncNum", ncNum);
        map.put("ncList", ncList);
        // 媒体成果
        int bzNum = this.getExpertFruitTypeNum(fruitDTO, ComConstant.FruitType.NewspaperORNetwork);
        List<ResultPercentPO> bzList = fruitRepository.getExpertDetailBzData(orgUserId, ComConstant.FruitType.NewspaperORNetwork);
        map.put("bzNum", bzNum);
        map.put("bzList", bzList);

        // 论文
        int lwNum = this.getExpertFruitTypeNum(fruitDTO, ComConstant.FruitType.Paper);
        List<ResultPercentPO> lwList = fruitRepository.getExpertDetailLwData(orgUserId, ComConstant.FruitType.Paper);
        map.put("lwNum", lwNum);
        map.put("lwList", lwList);
        // 报告
        int bgNum = this.getExpertFruitTypeNum(fruitDTO, ComConstant.FruitType.REPORT);
//        List<ResultPercentPO> bgList = fruitRepository.getExpertDetailBgData(orgUserId, ComConstant.FruitType.REPORT);
        map.put("bgNum", bgNum);
        map.put("bgList", null);

//        int zcNum = this.getExpertFruitTypeNum(fruitDTO, ComConstant.FruitType.PolicyAdvice);
//        List<ResultPercentPO> zcList = fruitRepository.getExpertDetailZcData(orgUserId, ComConstant.FruitType.PolicyAdvice);
        // 活动参与
        FruitParamsDTO fruitParamsDTO =  new FruitParamsDTO();
        FruitDTO fruitSearchDTO = new FruitDTO();
        fruitSearchDTO.setOrgUserId(OrgAccountHelper.getUserId());
        fruitSearchDTO.setType(ComConstant.FruitType.PolicyAdvice);
        fruitSearchDTO.setTerminal(ComConstant.ModuleTerminal.EXPERT);
        fruitParamsDTO.setSearchDto(fruitSearchDTO);
        List<ResultListFruitDTO> hdcyfriutList = this.readAll(fruitParamsDTO.getSearchDto(), fruitParamsDTO.getSortDto());

        Map<String, String> activityMap = ComConstant.descValueMapCons.get("ProductionActivityType");

        Map<String, Long> zcMap = hdcyfriutList.stream().filter(fruitPO -> !StringUtils.isEmpty(fruitPO.getActivityProdType()))
                .collect(Collectors.groupingBy(ResultListFruitDTO::getActivityProdType, Collectors.counting()));

        List<ResultPercentPO> zcList = zcMap.keySet().stream().map(key -> {
            ResultPercentPO resultPercentPO = new ResultPercentPO(activityMap.get(key), zcMap.get(key).longValue());
            return resultPercentPO;
        }).collect(Collectors.toList());

        map.put("zcNum", hdcyfriutList.size());
        map.put("zcList", zcList);
        // 图书
        int tsNum = this.getExpertFruitTypeNum(fruitDTO, ComConstant.FruitType.BOOK);
        List<ResultPercentPO> tsList = fruitRepository.getExpertDetailTsData(orgUserId, ComConstant.FruitType.BOOK);
        map.put("tsNum", tsNum);
        map.put("tsList", tsList);

        return map;
    }

    /**
     * 获取成果类型的数量
     * @param type
     * @return
     */
    public Integer getExpertFruitTypeNum(FruitDTO fruitDTO, String type){
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QOrgPo qOrgPo = QOrgPo.orgPo;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        Predicate predicate = qFruitPO.id.isNotNull()
                .and(qFruitPO.isDel.isFalse())
                .and(qFruitPO.isPublic.eq("0"))
                .and(qFruitPO.type.eq(type));
        long count = jpaQueryFactory.selectFrom(qFruitOrgRelPo)
                .leftJoin(qOrgPo).on(qFruitOrgRelPo.orgId.eq(qOrgPo.id))
                .leftJoin(qFruitPO).on(
                    buildOrgIdOrUserIdCondition(qFruitOrgRelPo, qFruitPO, fruitDTO, ComConstant.FruitStatus.APPROVED)
                )
                .where(predicate).fetchCount();
        return (int) count;
    }


    @Override
    public HashMap<String, Object> getExpertHomeLineData(FruitDTO fruitDTO) {

        HashMap<String, Object> map = new HashMap<>();
        Long orgUserId = fruitDTO.getOrgUserId();
        // 成果
        List<ResultLinePO> fruitList = fruitRepository.getFruitLineData(orgUserId);
        List<ResultLinePO> resultFruitList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        int currentYear = Integer.parseInt(sdf.format(new Date()));
        //获取近5年的数据
        for(int i=0;i<5;i++){
            ResultLinePO resultLinePO = new ResultLinePO();
            resultLinePO.setYearName((currentYear-i)+"");
            if(!CollectionUtils.isEmpty(fruitList)){
                boolean isHaveData = false;
                for(ResultLinePO rep:fruitList){
                    if(rep.getYearName().equals((currentYear-i)+"")){
                        isHaveData = true;
                        resultLinePO.setNum(rep.getNum());
                        break;
                    }
                }
                if(!isHaveData){
                    resultLinePO.setNum(0L);
                }
            }else{
                resultLinePO.setNum(0L);
            }
            resultFruitList.add(resultLinePO);
        }
        map.put("fruitList", resultFruitList);

        // 批示
        List<ResultLinePO> psList = fruitRepository.getPsLineData(orgUserId);
        List<ResultLinePO> resultPsList = new ArrayList<>();
        //获取近5年的数据
        for(int i=0;i<5;i++){
            ResultLinePO resultLinePO = new ResultLinePO();
            resultLinePO.setYearName((currentYear-i)+"");
            if(!CollectionUtils.isEmpty(psList)){
                boolean isHaveData = false;
                for(ResultLinePO rep:psList){
                    if(rep.getYearName().equals((currentYear-i)+"")){
                        isHaveData = true;
                        resultLinePO.setNum(rep.getNum());
                        break;
                    }
                }
                if(!isHaveData){
                    resultLinePO.setNum(0L);
                }
            }else{
                resultLinePO.setNum(0L);
            }
            resultPsList.add(resultLinePO);
        }
        map.put("psList", resultPsList);

        return map;
    }

    @Override
    public HashMap<String, Object> getExpertRelationData(FruitDTO fruitDTO) {
        //获取专家所有合作的机构
        List<ResultRelationPO> expertOrgList = fruitRepository.getRelationOrgData(fruitDTO.getOrgUserId());
        //根据数量排序 再按照机构名称排序 null放最后
        expertOrgList = expertOrgList.stream().sorted(Comparator.comparing(ResultRelationPO::getNum).reversed().thenComparing(ResultRelationPO::getName, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
        //获取专家所有合作的学着
        List<ResultRelationPO> expertAuthorList = fruitRepository.getRelationAuthorData(fruitDTO.getOrgUserId());

        HashMap<String, Object> map = new HashMap<>();
        map.put("expOrgList", expertOrgList);
        map.put("expAuthorList", expertAuthorList);

        return map;
    }


    //-------------------------------------------------------------------------------------------------------------------
    //----------------------------------------------------服务端----------------------------------------------------------
    //-------------------------------------------------------------------------------------------------------------------

    //专报拼装查询条件
    public Predicate getSpecialPredicates(QFruitPO qFruitPO, FruitParamsDTO fruitParamsDTO) {
        // 开启谓语查询条件
        Predicate predicate = qFruitPO.id.isNotNull().and(qFruitPO.isDel.isFalse());

        Predicate name_predicate = null;
        Predicate summary_predicate = null;
        Predicate remark_predicate = null;
        Predicate awards_predicate = null;
        Predicate theme_predicate = null;
        //---------------点击标签-------------
        String keyword = fruitParamsDTO.getHomeSearchDto().getKeyword();
        if (!StringUtils.isEmpty(keyword)) {
            predicate = ExpressionUtils.and(predicate,
                    qFruitPO.name.like("%" + keyword.trim() + "%")
                            .or(qFruitPO.summary.like("%" + keyword.trim() + "%"))
                            .or(qFruitPO.remark.like("%" + keyword.trim() + "%"))
                            .or(qFruitPO.awards.like("%" + keyword.trim() + "%"))
                            .or(qFruitPO.theme.like("%" + keyword.trim() + "%"))
            );
        }

        //---------------glm输入自然语言-------------
        String originContent = fruitParamsDTO.getHomeSearchDto().getContent();
        if (!StringUtils.isEmpty(originContent)) {
            // 调用模型来进行提取关键词及语义近义词
//            List<String> resultList = chatGptUtil.getKeyWordsAndSynonymsWord(content);
            //正则取值： 关于xxx的xx

            Matcher matcher = Pattern.compile("关于(.*?)的").matcher(originContent);
            String regexContent = originContent;
            if (matcher.find()) {
                regexContent = matcher.group(1);
                System.out.println("----匹配到的文本----" + regexContent);
            }
            //分析词云 提取
            TfIdfAnalyzer tfIdfAnalyzer = new TfIdfAnalyzer();
            try {
                List<String> list = tfIdfAnalyzer.keywords(regexContent);
                System.out.println("-----分析出的词------" + JSON.toJSONString(list));
                for (String cont : list) {
                    name_predicate = ExpressionUtils.or(name_predicate, qFruitPO.name.like("%" + cont + "%"));
                    summary_predicate = ExpressionUtils.or(summary_predicate, qFruitPO.summary.like("%" + cont + "%"));
                    remark_predicate = ExpressionUtils.or(remark_predicate, qFruitPO.remark.like("%" + cont + "%"));
                    awards_predicate = ExpressionUtils.or(awards_predicate, qFruitPO.awards.like("%" + cont + "%"));
                    theme_predicate = ExpressionUtils.or(theme_predicate, qFruitPO.theme.like("%" + cont + "%"));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
//            for (String cont : resultList) {
//                System.out.println("-----分析出的语义近义词------" + JSON.toJSONString(resultList));
//                if(!CollectionUtils.isEmpty(resultList)){
//                    //获取语义词对应的成果
//                    QWordSynonymsPo qWordSynonymsPo = QWordSynonymsPo.wordSynonymsPo;
//                    List<Long> fruitIdList = new ArrayList<>();
//                    if(!CollectionUtils.isEmpty(resultList)){
//                        for (String s : resultList) {
//                            fruitIdList.addAll(jpaQueryFactory.select(qWordSynonymsPo.fruitId).from(qWordSynonymsPo).where(qWordSynonymsPo.name.like("%" + s.trim() + "%")).fetch());
//                        }
//                    }
//                    if(!CollectionUtils.isEmpty(fruitIdList)){
//                        predicate = ExpressionUtils.and(predicate, qFruitPO.id.in(fruitIdList));
//                    }else{
//                        predicate = ExpressionUtils.and(predicate,
//                                qFruitPO.name.in(resultList) .or(qFruitPO.summary.in(resultList)));
//                    }
//                }
//
//                name_predicate = ExpressionUtils.or(name_predicate, qFruitPO.name.like("%" + cont + "%"));
//                summary_predicate = ExpressionUtils.or(summary_predicate, qFruitPO.summary.like("%" + cont + "%"));
//                remark_predicate = ExpressionUtils.or(remark_predicate, qFruitPO.remark.like("%" + cont + "%"));
//                awards_predicate = ExpressionUtils.or(awards_predicate, qFruitPO.awards.like("%" + cont + "%"));
//                theme_predicate = ExpressionUtils.or(theme_predicate, qFruitPO.theme.like("%" + cont + "%"));
//            }
            predicate = ExpressionUtils.and(predicate,
                    ExpressionUtils.anyOf(name_predicate, summary_predicate, remark_predicate, awards_predicate, theme_predicate)
            );

            //添加自定义处理方式
            predicate = buildCustomHandler(originContent, predicate, qFruitPO);
        }

        Long[] fruitIdList = fruitParamsDTO.getHomeSearchDto().getFruitIds();
        if(fruitIdList != null && fruitIdList.length > 0){
            predicate = ExpressionUtils.and(predicate, qFruitPO.id.in(fruitIdList));
        }

        //成果类型
        String type = fruitParamsDTO.getSearchDto().getType();
        if (!StringUtils.isEmpty(type)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(type));
        }

        //成果类型
        String[] typeArr = fruitParamsDTO.getHomeSearchDto().getTypeArr();
        if(typeArr != null && typeArr.length > 0){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.in(typeArr));
        }

        //是否智库专报
        String isSpecialSub = fruitParamsDTO.getSearchDto().getIsSpecialSub();
        if (!StringUtils.isEmpty(isSpecialSub)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.isSpecialSub.eq(isSpecialSub));
        }

        //是否调研点建设
        String isBuildResearch = fruitParamsDTO.getSearchDto().getIsBuildResearch();
        if (!StringUtils.isEmpty(isBuildResearch)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.isBuildResearch.eq(isBuildResearch));
        }

        //智库办 专报状态查询
        Integer specialSubDealStatus = fruitParamsDTO.getSearchDto().getSpecialSubDealStatus();
        if (specialSubDealStatus != null) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.subList.any().subDeptDealStatus.eq(specialSubDealStatus));
        }

        //智库专报查询
        String name = fruitParamsDTO.getSearchDto().getName();
        if (!StringUtils.isEmpty(name)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.name.like("%" + name.trim() + "%"));
        }
        Date pubStartTime = fruitParamsDTO.getSearchDto().getPubStartTime();
        Date pubEndTime = fruitParamsDTO.getSearchDto().getPubEndTime();
        if (null != pubStartTime) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.pubTime.goe(pubStartTime));
        }
        if (null != pubEndTime) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.pubTime.loe(pubEndTime));
        }

        return predicate;

    }

    //语言自定义处理方式
    public Predicate buildCustomHandler(String content, Predicate predicate, QFruitPO qFruitPO){
        if(content.contains("内参")){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(ComConstant.FruitType.InternalReferenceReport));
        }
        if(content.contains("报告")){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(ComConstant.FruitType.REPORT));
        }
        if(content.contains("活动")){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(ComConstant.FruitType.PolicyAdvice));
        }
        if(content.contains("会议")){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(ComConstant.FruitType.PolicyAdvice).or(qFruitPO.activityProdType.eq(ComConstant.FruitType.MEETING)));
        }
        if(content.contains("接待") || content.contains("来访")){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(ComConstant.FruitType.PolicyAdvice).or(qFruitPO.activityProdType.eq(ComConstant.FruitType.RECEIVE_VISITORS)));
        }
        if(content.contains("考察") || content.contains("调研")){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(ComConstant.FruitType.PolicyAdvice).or(qFruitPO.activityProdType.eq(ComConstant.FruitType.SURVEY)));
        }
        if(content.contains("授课") || content.contains("培训")){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(ComConstant.FruitType.PolicyAdvice).or(qFruitPO.activityProdType.eq(ComConstant.FruitType.TRAINING)));
        }
        if(content.contains("媒体")){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(ComConstant.FruitType.NewspaperORNetwork));
        }
        if(content.contains("采访") ){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(ComConstant.FruitType.NewspaperORNetwork).or(qFruitPO.activityProdType.eq(ComConstant.FruitType.MEDIA_INTERVIEW)));
        }
        if(content.contains("论文")){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(ComConstant.FruitType.Paper));
        }
        if(content.contains("图书")){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(ComConstant.FruitType.BOOK));
        }
        if(content.contains("荣誉")){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(ComConstant.FruitType.PRICE));
        }
        if(content.contains("项目")){
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(ComConstant.FruitType.PROJECT));
        }


        return predicate;
    }

    /**
     * 消费端首页查询成果分页--仅限公开成果
     * @return
     */
    @Override
    public Page<ResultServicesHomeListFruitDTO> readAllServicesFruitByPage(FruitParamsDTO fruitParamsDTO) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;

        Predicate predicate = this.getSpecialPredicates(qFruitPO, fruitParamsDTO);
        // 执行返回
        Pageable pageable = fruitParamsDTO.getPageDto().getPageable();

        JPAQuery<ResultServicesHomeListFruitDTO> listQuery = getServiceHomeFruit(qFruitPO, predicate, fruitParamsDTO.getSearchDto(), fruitParamsDTO.getSortDto());

        List<ResultServicesHomeListFruitDTO> list;

        boolean random = fruitParamsDTO.getRandom();
        if(random){
            List<ResultServicesHomeListFruitDTO> resultList = listQuery.fetch();
            //打乱
            Collections.shuffle(resultList);

            //分页
            int fromIndex = pageable.getPageSize()*pageable.getPageNumber();
            int toIndex = pageable.getPageSize()*(pageable.getPageNumber()+1);
            //#获取当前页数据
            toIndex = Math.min(resultList.size(), toIndex);

            list = resultList.subList(fromIndex, toIndex);
        }else{
            list = listQuery.offset(pageable.getPageNumber() * pageable.getPageSize())
                    .limit(pageable.getPageSize())
                    .fetch();
        }

        return new PageImpl<>(list, pageable, listQuery.fetchCount());
    }

    public JPAQuery<ResultServicesHomeListFruitDTO> getServiceHomeFruit(QFruitPO qFruitPO, Predicate predicate, FruitDTO searchDTO, SortParamsDTO sortParamsDto){
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        QFruitSubPO qFruitSubPO = QFruitSubPO.fruitSubPO;
        QOrgPo qOrgPo = QOrgPo.orgPo;

        //子查询 作者
        StringTemplate authorExpr = Expressions.stringTemplate("CONCAT(GROUP_CONCAT({0}),'')", qFruitAuthorPO.author);
        SubQueryExpression queryAuthor = JPAExpressions.select(authorExpr.as("authors")).from(qFruitAuthorPO)
                .where(qFruitAuthorPO.fruitId.eq(qFruitOrgRelPo.fruitId));
        //子查询 是否采纳  取最新的
//        SubQueryExpression queryIsAdopt = JPAExpressions.select(Expressions.stringTemplate("max({0})",qFruitSubPO.isAdopt)).from(qFruitSubPO)
//                .where(qFruitSubPO.fruitId.eq(qFruitOrgRelPo.fruitId).and(qFruitSubPO.adoptDeparment.like("%" + ComConstant.specialDeptName.JSSWXCB + "%")))
//                .orderBy(qFruitSubPO.subTime.desc()).limit(1);

        JPAQuery<ResultServicesHomeListFruitDTO> queryResults = jpaQueryFactory.select(
                Projections.constructor(ResultServicesHomeListFruitDTO.class,
                        qFruitPO.id,
                        qFruitPO.name,
                        qFruitPO.awards,
                        qFruitPO.type,
                        qFruitPO.activityProdType,
                        qFruitPO.pubTime,
                        qFruitPO.completionTime,
                        queryAuthor,
//                        queryIsAdopt,
                        qFruitPO.summary,
                        qFruitPO.linkUrl,
                        qFruitPO.linkAddress,
                        qOrgPo.id,
                        qOrgPo.nameZh,
                        qOrgPo.logo,
//                        qOrgPo.presetMgr.expertInfo.photo,
                        qOrgPo.presetMgr.realName,
                        qOrgPo.presetMgr.phoneNumber,
                        qOrgPo.presetMgr.mail,
                        qFruitPO.theme,
                        qFruitPO.press,
                        qFruitPO.journalName,
                        qFruitPO.meetingTypeName,
                        qFruitPO.visitTypeName,
                        qFruitPO.specialSubSource
                )
        )
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(
                        buildOrgIdOrUserIdCondition(qFruitOrgRelPo, qFruitPO, searchDTO, ComConstant.FruitStatus.APPROVED)
                )
                .leftJoin(qOrgPo).on(qFruitOrgRelPo.orgId.eq(qOrgPo.id))
                .where(qFruitPO.isPublic.eq("0"))
                .where(predicate)
                .orderBy(
//                        ("asc").equals(sortParamsDto.getSortDirection())?qFruitPO.pubTime.asc():qFruitPO.pubTime.desc()
                        qFruitPO.pubTime.desc(),
                        qFruitPO.type.asc()
                );

        return  queryResults;
    }


    /**
     * 消费端首页查询成果--仅限公开成果
     * @return
     */
    @Override
    public List<ResultServicesHomeListFruitDTO> readAllServicesFruitList(FruitParamsDTO fruitParamsDTO) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;

        // 开启谓语查询条件
        Predicate predicate = qFruitPO.id.isNotNull().and(qFruitPO.isDel.isFalse());

//        String name = fruitParamsDTO.getHomeSearchDto().getContent();
//        if (!StringUtils.isEmpty(name)) {
//            predicate = ExpressionUtils.and(predicate,
//                    qFruitPO.name.like("%" + name.trim() + "%")
//                            .or(qFruitPO.summary.like("%" + name.trim() + "%"))
//                            .or(qFruitPO.remark.like("%" + name.trim() + "%"))
//                            .or(qFruitPO.theme.like("%" + name.trim() + "%"))
//                            .or(qFruitPO.awards.like("%" + name.trim() + "%"))
//            );
//        }

        Predicate name_predicate = null;
        Predicate summary_predicate = null;
        Predicate remark_predicate = null;
        Predicate awards_predicate = null;
        Predicate theme_predicate = null;
        String content = fruitParamsDTO.getHomeSearchDto().getContent();
        if (!StringUtils.isEmpty(content)) {
            if(content.contains("+")){
                String[] conts = content.split("[+]");
                for (String cont : conts) {
                    name_predicate = ExpressionUtils.and(name_predicate,qFruitPO.name.like("%" + cont + "%"));
                    summary_predicate = ExpressionUtils.and(summary_predicate,qFruitPO.summary.like("%" + cont + "%"));
                    remark_predicate = ExpressionUtils.and(remark_predicate,qFruitPO.remark.like("%" + cont + "%"));
                    awards_predicate = ExpressionUtils.and(awards_predicate,qFruitPO.awards.like("%" + cont + "%"));
                    theme_predicate = ExpressionUtils.and(theme_predicate,qFruitPO.theme.like("%" + cont + "%"));
                }

                predicate = ExpressionUtils.and(predicate,
                        ExpressionUtils.anyOf(name_predicate, summary_predicate, remark_predicate, awards_predicate, theme_predicate)
                );
            }else{
                predicate = ExpressionUtils.and(predicate,
                        qFruitPO.name.like("%" + content.trim() + "%")
                                .or(qFruitPO.summary.like("%" + content.trim() + "%"))
                                .or(qFruitPO.remark.like("%" + content.trim() + "%"))
                                .or(qFruitPO.awards.like("%" + content.trim() + "%"))
                                .or(qFruitPO.theme.like("%" + content.trim() + "%"))
                );
            }
        }

        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;

        QueryResults<ResultServicesHomeListFruitDTO> queryResults = jpaQueryFactory.select(
                Projections.constructor(ResultServicesHomeListFruitDTO.class,
                        qFruitPO.name,
                        qFruitPO.summary,
                        qFruitPO.remark
                )
        )
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(
                    buildOrgIdOrUserIdCondition(qFruitOrgRelPo, qFruitPO, fruitParamsDTO.getSearchDto(), ComConstant.FruitStatus.APPROVED)
                )
                .where(qFruitPO.isPublic.eq("0"))
                .where(predicate)
                .fetchResults();

        return  queryResults.getResults();
    }


    /**
     * 智库专报-已采纳批示列表
     * @return
     */
    @Override
    public List<ResultServicesHomeListFruitDTO> readAllServicesSpecialFruitList(FruitParamsDTO fruitParamsDTO) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;

        Predicate predicate = this.getSpecialPredicates(qFruitPO, fruitParamsDTO);
        // 执行返回
        Pageable pageable = fruitParamsDTO.getPageDto().getPageable();

        JPAQuery<ResultServicesHomeListFruitDTO> listQuery = getServiceHomeFruit(qFruitPO, predicate, fruitParamsDTO.getSearchDto(), fruitParamsDTO.getSortDto());

        List<ResultServicesHomeListFruitDTO> list = listQuery.fetch();

        if(!CollectionUtils.isEmpty(list)){
            list.forEach(rsh -> {
                FruitPO fruitPO = fruitRepository.getOne(rsh.getId());
                rsh.setFruitSubPOList(fruitPO.getSubList());
                rsh.setFruitLeaderList(fruitPO.getLeaderPOS());
            });
        }

        return list;

    }

    /**
     * 消费端查看热力榜信息
     * @return
     */
    @Override
    public ResultServicesHomeListFruitDTO getFruitInfoAndOrgInfoById(Long fruitId) {
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        QFruitSubPO qFruitSubPO = QFruitSubPO.fruitSubPO;
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QOrgPo qOrgPo = QOrgPo.orgPo;

        //子查询 作者
        StringTemplate authorExpr = Expressions.stringTemplate("CONCAT(GROUP_CONCAT({0}),'')", qFruitAuthorPO.author);
        SubQueryExpression queryAuthor = JPAExpressions.select(authorExpr.as("authors")).from(qFruitAuthorPO)
                .where(qFruitAuthorPO.fruitId.eq(qFruitOrgRelPo.fruitId));

        ResultServicesHomeListFruitDTO result = jpaQueryFactory.select(
                Projections.constructor(ResultServicesHomeListFruitDTO.class,
                        qFruitPO.id,
                        qFruitPO.name,
                        qFruitPO.awards,
                        qFruitPO.type,
                        qFruitPO.activityProdType,
                        qFruitPO.pubTime,
                        qFruitPO.completionTime,
                        queryAuthor,
                        qFruitPO.summary,
                        qFruitPO.linkUrl,
                        qFruitPO.linkAddress,
                        qOrgPo.id,
                        qOrgPo.nameZh,
                        qOrgPo.logo,
                        qOrgPo.presetMgr.realName,
                        qOrgPo.presetMgr.phoneNumber,
                        qOrgPo.presetMgr.mail,
                        qFruitPO.theme,
                        qFruitPO.press,
                        qFruitPO.journalName,
                        qFruitPO.meetingTypeName,
                        qFruitPO.visitTypeName,
                        qFruitPO.specialSubSource
                )
        )
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(qFruitOrgRelPo.fruitId.eq(qFruitPO.id))
                .leftJoin(qOrgPo).on(qFruitOrgRelPo.orgId.eq(qOrgPo.id))
                .where(qFruitPO.isPublic.eq("0")
                                .and(qFruitOrgRelPo.status.eq(ComConstant.FruitStatus.APPROVED)))
                .where(qFruitPO.id.eq(fruitId))
                .fetchOne();

        return result;
    }

    @Override
    public void acceptSpecial(FruitPO fruitPo, FruitSubPO fruitSubPO) {
        List<FruitSubPO> fruitSubPOList = fruitPo.getSubList();
        FruitSubPO fsNew = new FruitSubPO();
        for (FruitSubPO fsp : fruitSubPOList) {
            //获取智库专报那一条报送信息
            if((ComConstant.specialDeptName.JSSWXCB).equals(fsp.getSubDeparment()) && fsp.getSubDeptType() != null && fsp.getSubDeptType() == 1  ){
                BeanUtils.copyProperties(fsp, fsNew);

                fsNew.setIsAdopt(true);
                fsNew.setAdoptDeparment(ComConstant.specialDeptName.JSSWXCB);
                fsNew.setSubDeptDealStatus(1);
                fsNew.setAdoptTime(fruitSubPO.getAdoptTime());
                fsNew.setAdoptJournal(fruitSubPO.getAdoptJournal());
                fsNew.setRemark(fruitSubPO.getRemark());
                fsNew.setAttFiles(fruitSubPO.getAttFiles());
                break;
            }
        };
        fruitSubRepository.save(fsNew);
    }

    @Override
    public void refuseSpecial(FruitPO fruitPo) {
        this.dealSub(fruitPo, 2);
    }

    @Override
    public void revocationSpecial(FruitPO fruitPo) {
        this.dealSub(fruitPo, 0);
    }

    public void dealSub(FruitPO fruitPo, int status){
        List<FruitSubPO> fruitSubPOList = fruitPo.getSubList();
        FruitSubPO fsNew = new FruitSubPO();
        for (FruitSubPO fsp : fruitSubPOList) {
            //获取智库专报那一条报送信息
            if((ComConstant.specialDeptName.JSSWXCB).equals(fsp.getSubDeparment()) && fsp.getSubDeptType() != null && fsp.getSubDeptType() == 1 ){
                BeanUtils.copyProperties(fsp, fsNew);
                fsNew.setSubDeptDealStatus(status);
                break;
            }
        };
        fruitSubRepository.save(fsNew);
    }

    @Override
    public void inputPsSpecial(FruitLeaderPO fruitLeaderPO) {
        //新增批示时
        if(fruitLeaderPO.getId() == null){
            fruitLeaderPO.setInputType(1);
        }
        fruitLeaderRepository.save(fruitLeaderPO);
    }

    @Override
    public void deletePsSpecial(FruitLeaderPO fruitLeaderPO) {
        fruitLeaderRepository.delete(fruitLeaderPO);
    }


    @Override
    public void inputSpecialFk(FruitFeedBackPO fruitFeedBackPO) {
        fruitSpecialFeedBackRepository.save(fruitFeedBackPO);
    }

    @Override
    public void deleteSpecialFk(FruitFeedBackPO fruitFeedBackPO) {
        fruitSpecialFeedBackRepository.delete(fruitFeedBackPO);
    }

    @Override
    public void updateFruitFeedBackByFruitId(FruitFeedBackPO fruitFeedBackPO) {
        fruitSpecialFeedBackRepository.updateFruitFeedBackByFruitId(fruitFeedBackPO.getFruitId());
    }

    /**
     *
     * 智库管理--智库详情--获取所有成果的信息
     *
     * @return
     */
    @Override
    public Page<ResultHomeListFruitDTO> getAllFruitOfPageByOrgId(FruitParamsDTO dto) {

        QFruitPO qFruitPO = QFruitPO.fruitPO;
        // 开启谓语查询条件
        Predicate predicate = getPredicates(qFruitPO, dto.getSearchDto());

        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QFruitAuthorPO qFruitAuthorPO = QFruitAuthorPO.fruitAuthorPO;
        QFruitSubPO qFruitSubPO = QFruitSubPO.fruitSubPO;
        Long orgId = dto.getSearchDto().getOrgId();
        // 执行返回
        Pageable pageable = dto.getPageDto().getPageable();

        //子查询 作者
        StringTemplate authorExpr = Expressions.stringTemplate("CONCAT(GROUP_CONCAT({0}),'')", qFruitAuthorPO.author);
        SubQueryExpression queryAuthor = JPAExpressions.select(authorExpr.as("authors")).from(qFruitAuthorPO)
                .where(qFruitAuthorPO.fruitId.eq(qFruitOrgRelPo.fruitId));

        QueryResults<ResultHomeListFruitDTO> queryResults = jpaQueryFactory.select(
                Projections.constructor(ResultHomeListFruitDTO.class,
                        qFruitPO.id,
                        qFruitPO.name,
                        qFruitPO.type,
                        qFruitPO.activityProdType,
                        qFruitPO.pubTime,
                        queryAuthor
                )
        )
                .from(qFruitOrgRelPo)
                .leftJoin(qFruitPO).on(
                        buildOrgIdOrUserIdCondition(qFruitOrgRelPo, qFruitPO, dto.getSearchDto(), ComConstant.FruitStatus.APPROVED)
                )
                .where(predicate)
                .orderBy(
                      qFruitPO.pubTime.desc()
                )
                .offset(pageable.getPageNumber() * pageable.getPageSize())
                .limit(pageable.getPageSize())
                .fetchResults();

        return  new PageImpl<>(queryResults.getResults(), pageable, queryResults.getTotal());

    }

    @Override
    public Page<ResultServicesReportInfoDTO> readAllReportInformationByPage(FruitParamsDTO dto) {

        Long userId = ServiceAccountHelper.getUserId();
        //课题数据
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QOrgPo qOrgPo = QOrgPo.orgPo;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        //开启谓语查询条件
        Predicate predicate = getPredicates(qFruitPO, dto.getSearchDto());

        Long orgId = dto.getSearchDto().getOrgId();
        if (null != orgId && orgId.longValue() > 0) {
            predicate = ExpressionUtils.and(predicate, qOrgPo.id.eq(orgId));
        }
        //类型
        List<String> typeList = new ArrayList<>();
        typeList.add(ComConstant.FruitType.NewspaperORNetwork);
        typeList.add(ComConstant.FruitType.PolicyAdvice);
        predicate = ExpressionUtils.and(predicate, qFruitPO.type.in(typeList));

        List<ResultServicesReportInfoDTO> list = new ArrayList<>();
        //查询
        jpaQueryFactory.select(
                Projections.constructor(ResultServicesReportInfoDTO.class,
                        qFruitPO.id,
                        qFruitPO.name,
                        qFruitPO.type,
                        qFruitPO.activityProdType,
                        qFruitPO.pubTime,
                        qOrgPo.id,
                        qOrgPo.shortNameZh,
                        qFruitPO.organizer,
                        qFruitPO.linkUrl
                )
        )
        .from(qFruitOrgRelPo)
        .leftJoin(qOrgPo).on(qFruitOrgRelPo.orgId.eq(qOrgPo.id))
        .leftJoin(qFruitPO).on(
                buildOrgIdOrUserIdCondition(qFruitOrgRelPo, qFruitPO, dto.getSearchDto(), ComConstant.FruitStatus.APPROVED)
        )
        .where(qFruitPO.isPublic.eq("0"))
        .where(predicate)
        .groupBy(qFruitPO.id)
        .orderBy(qFruitPO.pubTime.desc())
        .fetch().stream().forEach(rsriInfo -> {
            //出席会议--主办是自己的
            if((ComConstant.FruitType.MEETING).equals(rsriInfo.getActivityProdType())){
                //机构关键字
                QOrgKeywordPo qOrgKeywordPo = QOrgKeywordPo.orgKeywordPo;
                Set<String> keywordsList = jpaQueryFactory.select(qOrgKeywordPo).from(qOrgKeywordPo).where(qOrgKeywordPo.org.id.eq(rsriInfo.getOrgId())).fetch()
                        .stream().map(orgKeywordPo -> orgKeywordPo.getName()).collect(Collectors.toSet());
                if(OrgKeyWordsUtil.matchKeyWords(rsriInfo.getOrganizer() != null ? rsriInfo.getOrganizer() : "", keywordsList)){
                    list.add(rsriInfo);
                }
            }else{
                list.add(rsriInfo);
            }
        });

        //执行返回
        Pageable pageable = dto.getPageDto().getPageable();
        //分页
        int fromIndex = pageable.getPageSize()*pageable.getPageNumber();
        int toIndex = pageable.getPageSize()*(pageable.getPageNumber()+1);
        //#获取当前页数据
        toIndex = Math.min(list.size(), toIndex);

        List<ResultServicesReportInfoDTO> resultList = list.subList(fromIndex,toIndex);

        return new PageImpl<>(resultList, pageable, list.size());
    }





    /**
     * 获取审核通过的成果---专家删除了也能看到，isdel条件不添加
     * @return
     */
    @Override
    public List<FruitPO> getCheckFruits(FruitDTO searchDTO){

        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        Predicate predicate = getPredicates(qFruitPO, searchDTO);
        String fruitType = searchDTO.getType();
        if (!StringUtils.isEmpty(fruitType) && !("0").equals(fruitType)) {
            predicate = ExpressionUtils.and(predicate, qFruitPO.type.eq(fruitType));
        }
        if(searchDTO.getId() != null){
            predicate = ExpressionUtils.and(predicate, qFruitPO.id.eq(searchDTO.getId()));
        }
        List<FruitPO> agreeFruitList = jpaQueryFactory.select(qFruitPO).from(qFruitPO, qFruitOrgRelPo).where(qFruitPO.id.eq(qFruitOrgRelPo.fruitId)
                .and(qFruitOrgRelPo.orgId.eq(searchDTO.getOrgId())).and(predicate).and(qFruitOrgRelPo.status.eq("1"))).fetch();

        return agreeFruitList;
    }

    @Override
    public void deleteFruitOrgRelPosByFruitIdAndOrgIdAndStatus(long fruitId, long orgId, String status){
        fruitOrgRelRepository.deleteFruitOrgRelPosByFruitIdAndOrgIdAndStatus(fruitId, orgId, status);
    }

    /**
     * 新增机构与成果对应关系
     * @param orgId
     * @param fruitId
     * @param status
     */
    @Override
    public void createFruitOrgOrExpertRel(Long orgId, Long userId, Long fruitId, Long initFruitId, String status) {
        FruitOrgRelPo fruitOrgRelPo = new FruitOrgRelPo();
        fruitOrgRelPo.setOrgId(orgId);
        fruitOrgRelPo.setAuthUserId(userId);
        fruitOrgRelPo.setFruitId(fruitId);
        fruitOrgRelPo.setInitFruitId(initFruitId);
        fruitOrgRelPo.setStatus(status);
        fruitOrgRelRepository.save(fruitOrgRelPo);
    }


    /**
     * 删除成果
     * @param id 成果id
     */
    @Override
    public void expertDelete(Long id) {
        fruitOrgRelRepository.deleteFruitOrgRelPosByFruitIdAndAuthUserId(id ,OrgAccountHelper.getUserId());
//        FruitPO fruitPO = fruitRepository.findById(id).orElse(null);
//        if(fruitPO != null){
//            //逻辑删除，将删除状态改为true---如果作者只有一个且是自己
//            Long userId = OrgAccountHelper.getUserId();
//            if(fruitPO.getAuthorPOList().size() == 1 && fruitPO.getAuthorPOList().get(0).getOrgUserId().equals(userId)){
//                fruitPO.setIsDel(true);
//            }
//            //将成果里对应的作者和作者单位，状态置为删除---只删除自己的那个对应关系
//            if (!CollectionUtils.isEmpty(fruitPO.getAuthorPOList())) {
//                for (FruitAuthorPO fruitAuthorPO : fruitPO.getAuthorPOList()) {
//                    //只删除自己的那个对应关系
//                    if(fruitAuthorPO.getOrgUserId().equals(userId)){
//                        fruitAuthorPO.setIsDel(true);
//                        if (!CollectionUtils.isEmpty(fruitAuthorPO.getOrgPOList())) {
//                            for (FruitAuthorOrgPO fruitAuthorOrgPO : fruitAuthorPO.getOrgPOList()) {
//                                fruitAuthorOrgPO.setIsDel(true);
//                            }
//                        }
//                    }
//                }
//            }
//            fruitRepository.save(fruitPO);
//        }else{
//            //删除对应关系--待审核的
//            fruitOrgRelRepository.deleteFruitOrgRelPosByFruitIdAndStatus(id, ComConstant.FruitStatus.WATICHECK);
//        }

    }

    public int validateValue(Long value){
        return value == null ? 0 : value.intValue();
    }

    public Map<String, Long> getPsLevelFruitNum(List<Long> allFruitIdList){
        QFruitLeaderPO qFruitLeaderPO = QFruitLeaderPO.fruitLeaderPO;
        //查询结果集并转成map
        Map<String, Long> levelMap = jpaQueryFactory.select(qFruitLeaderPO.inclinationLevel.min(), qFruitLeaderPO.fruitId).from(qFruitLeaderPO)
                .where(qFruitLeaderPO.inclinationLevel.isNotNull()
                        .and(qFruitLeaderPO.fruitId.isNotNull()).and(qFruitLeaderPO.fruitId.in(allFruitIdList))).fetch().stream()
                .map(
                        tuple -> {
                            ResultPercentPO resultPercentPO = new ResultPercentPO();
                            if(tuple.get(qFruitLeaderPO.fruitId) != null && tuple.get(qFruitLeaderPO.inclinationLevel.min()) != null ) {
                                resultPercentPO.setResultName(tuple.get(qFruitLeaderPO.inclinationLevel.min()));
                                resultPercentPO.setNum(tuple.get(qFruitLeaderPO.fruitId));
                            }
                            return resultPercentPO;
                        }
                ).filter(dto-> !StringUtils.isEmpty(dto.getResultName()))
                .collect(Collectors.groupingBy(o -> o.getResultName(), Collectors.counting()));
        return levelMap;
    }

    //获取报送级别中最小的值的分组
    public Map<String, Long> getBsAndPsLevelFruitNum(List<Long> fruitIdList){
        //查询报送结果集并转成map
        QFruitSubPO qFruitSubPO = QFruitSubPO.fruitSubPO;
        Map<String, Long> bsLevelMap = jpaQueryFactory.select(qFruitSubPO.level.min(), qFruitSubPO.fruitId).from(qFruitSubPO)
                .where(qFruitSubPO.level.isNotNull().and(qFruitSubPO.level.isNotEmpty())
                        .and(qFruitSubPO.fruitId.isNotNull()).and(qFruitSubPO.fruitId.in(fruitIdList))).fetch().stream()
                .map(
                        tuple -> {
                            ResultPercentPO resultPercentPO = new ResultPercentPO();
                            if(tuple.get(qFruitSubPO.fruitId) != null && tuple.get(qFruitSubPO.level.min()) != null ){
                                resultPercentPO.setNum(Long.parseLong(tuple.get(qFruitSubPO.level.min())));
                                resultPercentPO.setResultName(tuple.get(qFruitSubPO.fruitId).toString());
                            }
                            return resultPercentPO;
                        }
                ).filter(dto-> !StringUtils.isEmpty(dto.getResultName()) && !StringUtils.isEmpty(dto.getNum()))
                .collect(Collectors.toMap(ResultPercentPO::getResultName, ResultPercentPO::getNum));

        //查询结果集并转成map
        QFruitLeaderPO qFruitLeaderPO = QFruitLeaderPO.fruitLeaderPO;
        Map<String, Long> psLevelMap = jpaQueryFactory.select(qFruitLeaderPO.inclinationLevel.min(), qFruitLeaderPO.fruitId).from(qFruitLeaderPO)
                .where(qFruitLeaderPO.inclinationLevel.isNotNull()
                        .and(qFruitLeaderPO.fruitId.isNotNull()).and(qFruitLeaderPO.fruitId.in(fruitIdList))).fetch().stream()
                .map(
                        tuple -> {
                            ResultPercentPO resultPercentPO = new ResultPercentPO();
                            if(tuple.get(qFruitLeaderPO.fruitId) != null && tuple.get(qFruitLeaderPO.inclinationLevel.min()) != null ) {
                                resultPercentPO.setNum(Long.parseLong(tuple.get(qFruitLeaderPO.inclinationLevel.min())));
                                resultPercentPO.setResultName(tuple.get(qFruitLeaderPO.fruitId).toString());
                            }
                            return resultPercentPO;
                        }
                ).filter(dto-> !StringUtils.isEmpty(dto.getResultName()) && !StringUtils.isEmpty(dto.getNum()))
                .collect(Collectors.toMap(ResultPercentPO::getResultName, ResultPercentPO::getNum));
//                .collect(HashMap::new,(m, v)->m.put(v.getResultName(), v.getNum()), HashMap::putAll);

        //两个map合并并比较大小----取最小的----
        Map<String, Long> tmpMap = Stream.concat(bsLevelMap.entrySet().stream().filter((e)-> e.getKey() != null && e.getValue() != null),
                psLevelMap.entrySet().stream().filter((e)-> e.getKey() != null && e.getValue() != null))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,(value1, value2) -> value1 >= value2?value2:value1));
        //根据level分组
        Map<String, Long> resultMap = tmpMap.entrySet().stream().collect(Collectors.groupingBy(c -> c.getValue().toString(), Collectors.counting()));

        return resultMap;
    }
//    @Override
//    public int findExistsPublication(FruitDTO dto) {
//        return fruitRepository.findExistsByNameAndID(dto.getName(), dto.getType(), dto.getOrgId(), dto.getId(), dto.getIssueNumber());
//    }



//    private int getResultPOS(SysDict sysDict, String month, Long orgId) {
//
//        StringBuffer querySql = new StringBuffer("  select\n" +
//                "        count(f.type) as num \n" +
//                "    from\n" +
//                "        biz_fruit  f\n" +
//                "    where\n" +
//                "        (\n" +
//                "            f.is_del = 0\n" +
//                "        )");
//        querySql.append(" and f.type=:type ");
//        querySql.append(" and date_format(f.pub_time, '%Y-%m')=:month ");
//        if (null != orgId && orgId.longValue() > 0) {
//            querySql.append(" and f.org_id=:orgId ");
//        }
//        Query query = entityManager.createNativeQuery(querySql.toString());
//        query.setParameter("type", sysDict.getDvalue());
//        query.setParameter("month", month);
//        if (null != orgId && orgId.longValue() > 0) {
//            query.setParameter("orgId", orgId);
//        }
//        Object obj = query.getSingleResult();
//        return Integer.valueOf(obj.toString());
//    }

//
//    private String getInclinationLevelPOS(SysDict sysDict, String type, Date startTime, Date endTime, Long orgId) {
//
//        StringBuffer querySql = new StringBuffer("select  count(1) from biz_fruit a\n" +
//                "RIGHT JOIN biz_fruit_leader b ON a.id=b.fruit_id  where  a.is_del='0' ");
//        querySql.append(" and a.type=:type ");
//        if (null != startTime) {
//            querySql.append("and date_format(a.pub_time, '%Y-%m')>=:startTime ");
//        }
//        if (null != endTime) {
//            querySql.append("and  date_format(a.pub_time, '%Y-%m')<=:endTime ");
//        }
//        if (null != orgId && orgId.longValue() > 0) {
//            querySql.append(" and a.org_id=:orgId ");
//        }
//        querySql.append(" and inclination_level=:inclinationLevel ");
//        Query query = entityManager.createNativeQuery(querySql.toString());
//        query.setParameter("inclinationLevel", sysDict.getDvalue());
//        if (null != startTime) {
//            query.setParameter("startTime", startTime);
//        }
//        if (null != endTime) {
//            query.setParameter("endTime", endTime);
//        }
//        if (null != orgId && orgId.longValue() > 0) {
//            query.setParameter("orgId", orgId);
//        }
//        query.setParameter("type", type);
//        Object obj = query.getSingleResult();
//        return obj.toString();
//    }
//
//    private String getReportTypePOS(SysDict sysDict, String type, Date startTime, Date endTime, Long orgId) {
//
//        StringBuffer querySql = new StringBuffer("select  count(1) from biz_fruit a\n" +
//                "where  a.is_del='0' ");
//        querySql.append(" and a.type=:type ");
//        if (null != startTime) {
//            querySql.append("and date_format(a.pub_time, '%Y-%m')>=:startTime ");
//        }
//        if (null != endTime) {
//            querySql.append("and  date_format(a.pub_time, '%Y-%m')<=:endTime ");
//        }
//        if (null != orgId && orgId.longValue() > 0) {
//            querySql.append(" and a.org_id=:orgId ");
//        }
//        querySql.append(" and report_type=:report_type");
//        Query query = entityManager.createNativeQuery(querySql.toString());
//        query.setParameter("report_type", sysDict.getDvalue());
//        if (null != startTime) {
//            query.setParameter("startTime", startTime);
//        }
//        if (null != endTime) {
//            query.setParameter("endTime", endTime);
//        }
//        if (null != orgId && orgId.longValue() > 0) {
//            query.setParameter("orgId", orgId);
//        }
//        query.setParameter("type", type);
//        Object obj = query.getSingleResult();
//        return obj.toString();
//    }
//
//    private String getPolicyTypePOS(SysDict sysDict, String type, Date startTime, Date endTime, Long orgId) {
//
//        StringBuffer querySql = new StringBuffer("select  count(1) from biz_fruit a\n" +
//                "  where  a.is_del='0' ");
//        querySql.append(" and a.type=:type ");
//        if (null != startTime) {
//            querySql.append("and date_format(a.pub_time, '%Y-%m')>=:startTime ");
//        }
//        if (null != endTime) {
//            querySql.append("and  date_format(a.pub_time, '%Y-%m')<=:endTime ");
//        }
//        if (null != orgId && orgId.longValue() > 0) {
//            querySql.append(" and a.org_id=:orgId ");
//        }
//        querySql.append(" and policy_type=:policy_type");
//        Query query = entityManager.createNativeQuery(querySql.toString());
//        query.setParameter("policy_type", sysDict.getDvalue());
//        if (null != startTime) {
//            query.setParameter("startTime", startTime);
//        }
//        if (null != endTime) {
//            query.setParameter("endTime", endTime);
//        }
//        if (null != orgId && orgId.longValue() > 0) {
//            query.setParameter("orgId", orgId);
//        }
//        query.setParameter("type", type);
//        Object obj = query.getSingleResult();
//        return obj.toString();
//    }
//
//    private String getJournalTypePOS(SysDict sysDict, String type, Date startTime, Date endTime, Long orgId) {
//
//        StringBuffer querySql = new StringBuffer("select  count(1) from biz_fruit a\n" +
//                "  where  a.is_del='0' ");
//        querySql.append(" and a.type=:type ");
//        if (null != startTime) {
//            querySql.append("and date_format(a.pub_time, '%Y-%m')>=:startTime ");
//        }
//        if (null != endTime) {
//            querySql.append("and  date_format(a.pub_time, '%Y-%m')<=:endTime ");
//        }
//        if (null != orgId && orgId.longValue() > 0) {
//            querySql.append(" and a.org_id=:orgId ");
//        }
//        querySql.append(" and journal_type=:journal_type");
//        Query query = entityManager.createNativeQuery(querySql.toString());
//        query.setParameter("journal_type", sysDict.getDvalue());
//        if (null != startTime) {
//            query.setParameter("startTime", startTime);
//        }
//        if (null != endTime) {
//            query.setParameter("endTime", endTime);
//        }
//        if (null != orgId && orgId.longValue() > 0) {
//            query.setParameter("orgId", orgId);
//        }
//        query.setParameter("type", type);
//        Object obj = query.getSingleResult();
//        return obj.toString();
//    }
//
//
//    private String getAwardLevelPOS(SysDict sysDict, String type, Date startTime, Date endTime, Long orgId) {
//
//        StringBuffer querySql = new StringBuffer("select  count(1) from biz_fruit a\n" +
//                "  where  a.is_del='0' ");
//        querySql.append(" and a.type=:type ");
//        if (null != startTime) {
//            querySql.append("and date_format(a.pub_time, '%Y-%m')>=:startTime ");
//        }
//        if (null != endTime) {
//            querySql.append("and  date_format(a.pub_time, '%Y-%m')<=:endTime ");
//        }
//        if (null != orgId && orgId.longValue() > 0) {
//            querySql.append(" and a.org_id=:orgId ");
//        }
//        querySql.append(" and awards_level=:awards_level");
//        Query query = entityManager.createNativeQuery(querySql.toString());
//        query.setParameter("awards_level", sysDict.getDvalue());
//        if (null != startTime) {
//            query.setParameter("startTime", startTime);
//        }
//        if (null != endTime) {
//            query.setParameter("endTime", endTime);
//        }
//        if (null != orgId && orgId.longValue() > 0) {
//            query.setParameter("orgId", orgId);
//        }
//        query.setParameter("type", type);
//        Object obj = query.getSingleResult();
//        return obj.toString();
//    }
//

//    // 前最近N个月
//    private String getLastNMonths(int i) {
//        Calendar c = Calendar.getInstance();
//        c.setTime(new Date());
//        c.add(Calendar.MONTH, -i);
//        int year = c.get(Calendar.YEAR);
//        int month = c.get(Calendar.MONTH) + 1;
//        String date;
//        if (month < 10) {
//            date = year + "-0" + month;
//        } else {
//            date = year + "-" + month;
//        }
//        return date;
//    }


//
//    /**
//     *  获取两个之前的月份
//     * @param minDate
//     * @param maxDate
//     * @return
//     * @throws ParseException
//     */
//    public static List<String> getMonthBetween(Date minDate, Date maxDate) {
//        ArrayList<String> result = new ArrayList<String>();
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月
//        Calendar min = Calendar.getInstance();
//        Calendar max = Calendar.getInstance();
//        min.setTime(minDate);
//        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
//        max.setTime(maxDate);
//        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
//        Calendar curr = min;
//        while (curr.before(max)) {
//            result.add(sdf.format(curr.getTime()));
//            curr.add(Calendar.MONTH, 1);
//        }
//        return result;
//    }



    //查找成果批示里面不同级别数据
//        "SELECT\n" +
//                "	count( minLevel.fruit_id ),\n" +
//                "	minLevel.fruit_id,\n" +
//                "	minLevel.ml \n" +
//                "FROM\n" +
//                "	(\n" +
//                "SELECT\n" +
//                "	min( bf.inclination_level ) AS ml,\n" +
//                "	bf.fruit_id \n" +
//                "FROM\n" +
//                "	biz_fruit_leader bf \n" +
//                "WHERE\n" +
//                "	bf.inclination_level IS NOT NULL \n" +
//                "	AND bf.fruit_id IS NOT NULL \n" +
//                "GROUP BY\n" +
//                "	bf.fruit_id \n" +
//                "	) minLevel \n" +
//                "GROUP BY\n" +
//                "	minLevel.ml"

    /**
     * 获取内参报送采纳篇数
     * @param dto
     * @return
     */
    @Override
    public long getFruitSubPiece(String classify, ScreenSearchConditionDTO dto) {
        QOrgPo qOrgPo = QOrgPo.orgPo;
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QFruitSubPO qFruitSubPO = QFruitSubPO.fruitSubPO;

        Predicate predicate = qFruitPO.id.isNotNull().and(qFruitPO.isDel.isFalse()).and(qFruitPO.isPublic.eq("0")
                                .and(qFruitPO.type.eq(ComConstant.FruitType.InternalReferenceReport)));


        // 报送采纳条件拼接
        Predicate subPredicate = qFruitSubPO.fruitId.isNotNull();
        if(("cn").equals(classify)){
            subPredicate = ExpressionUtils.and(subPredicate, qFruitSubPO.isAdopt.isTrue());

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date pubStartTime = dto.getPubStartTime();
            Date pubEndTime = dto.getPubEndTime();
            StringTemplate dateExpr = Expressions.stringTemplate("DATE_FORMAT({0},'%Y-%m-%d')", qFruitSubPO.adoptTime);

            if (null != pubStartTime) {
                subPredicate = ExpressionUtils.and(subPredicate, dateExpr.goe(sdf.format(pubStartTime)));
            }
            if (null != pubEndTime) {
                subPredicate = ExpressionUtils.and(subPredicate, dateExpr.loe(sdf.format(pubEndTime)));
            }
            if (dto.getYearNumber() != null) {
                subPredicate = ExpressionUtils.and(subPredicate, qFruitSubPO.adoptTime.year().eq(dto.getYearNumber()));
            }
        }

        Set<Long> fruitIdList = new HashSet<>();
        jpaQueryFactory.select(qFruitSubPO.fruitId, qFruitSubPO.level.min())
                .from(qFruitSubPO).where(subPredicate).groupBy(qFruitSubPO.fruitId).fetch()
                .stream().forEach(tuple -> {
            fruitIdList.add(tuple.get(qFruitSubPO.fruitId));
        });

        long subFruitCount = jpaQueryFactory.select(qFruitOrgRelPo.fruitId)
                .from(qOrgPo)
                .leftJoin(qFruitOrgRelPo).on(qFruitOrgRelPo.orgId.eq(qOrgPo.id)
                        .and(qFruitOrgRelPo.status.eq(ComConstant.FruitStatus.APPROVED)))
                .leftJoin(qFruitPO).on(qFruitPO.id.eq(qFruitOrgRelPo.fruitId))
                .where(qOrgPo.deleted.isFalse().and(predicate).and(qFruitOrgRelPo.fruitId.in(fruitIdList)))
                .where(qOrgPo.id.in(dto.getOrgIdList()))
                .fetchCount();

        return subFruitCount;
    }


    /**
     * 获取内参批示篇数
     * @param dto
     * @return
     */
    @Override
    public long getFruitPsPiece(ScreenSearchConditionDTO dto) {

        QFruitLeaderPO qFruitLeaderPO = QFruitLeaderPO.fruitLeaderPO;
        Predicate leaderPredicate = qFruitLeaderPO.fruitId.isNotNull();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date pubStartTime = dto.getPubStartTime();
        Date pubEndTime = dto.getPubEndTime();
        StringTemplate dateExpr = Expressions.stringTemplate("DATE_FORMAT({0},'%Y-%m-%d')", qFruitLeaderPO.inclinationTime);

        if (null != pubStartTime) {
            leaderPredicate = ExpressionUtils.and(leaderPredicate, dateExpr.goe(sdf.format(pubStartTime)));
        }
        if (null != pubEndTime) {
            leaderPredicate = ExpressionUtils.and(leaderPredicate, dateExpr.loe(sdf.format(pubEndTime)));
        }
        if (dto.getYearNumber() != null) {
            leaderPredicate = ExpressionUtils.and(leaderPredicate, qFruitLeaderPO.inclinationTime.year().eq(dto.getYearNumber()));
        }
        return this.getFruitPsPieceData(dto.getOrgIdList(), leaderPredicate);
    }


    /**
     * 获取内参批示篇数--正国级
     * @param dto
     * @return
     */
    @Override
    public long getFruitPsZgjPiece(ScreenSearchConditionDTO dto) {

        QFruitLeaderPO qFruitLeaderPO = QFruitLeaderPO.fruitLeaderPO;
        Predicate leaderPredicate = qFruitLeaderPO.fruitId.isNotNull().and(qFruitLeaderPO.inclinationLevel.eq("1"));

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date pubStartTime = dto.getPubStartTime();
        Date pubEndTime = dto.getPubEndTime();
        StringTemplate dateExpr = Expressions.stringTemplate("DATE_FORMAT({0},'%Y-%m-%d')", qFruitLeaderPO.inclinationTime);

        if (null != pubStartTime) {
            leaderPredicate = ExpressionUtils.and(leaderPredicate, dateExpr.goe(sdf.format(pubStartTime)));
        }
        if (null != pubEndTime) {
            leaderPredicate = ExpressionUtils.and(leaderPredicate, dateExpr.loe(sdf.format(pubEndTime)));
        }
        if (dto.getYearNumber() != null) {
            leaderPredicate = ExpressionUtils.and(leaderPredicate, qFruitLeaderPO.inclinationTime.year().eq(dto.getYearNumber()));
        }

        return this.getFruitPsPieceData(dto.getOrgIdList(), leaderPredicate);
    }

    /**
     * 获取内参批示篇数--副国级
     * @param dto
     * @return
     */
    @Override
    public long getFruitPsFgjPiece(ScreenSearchConditionDTO dto) {

        QFruitLeaderPO qFruitLeaderPO = QFruitLeaderPO.fruitLeaderPO;
        Predicate leaderPredicate = qFruitLeaderPO.fruitId.isNotNull().and(qFruitLeaderPO.inclinationLevel.eq("2"));

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date pubStartTime = dto.getPubStartTime();
        Date pubEndTime = dto.getPubEndTime();
        StringTemplate dateExpr = Expressions.stringTemplate("DATE_FORMAT({0},'%Y-%m-%d')", qFruitLeaderPO.inclinationTime);

        if (null != pubStartTime) {
            leaderPredicate = ExpressionUtils.and(leaderPredicate, dateExpr.goe(sdf.format(pubStartTime)));
        }
        if (null != pubEndTime) {
            leaderPredicate = ExpressionUtils.and(leaderPredicate, dateExpr.loe(sdf.format(pubEndTime)));
        }
        if (dto.getYearNumber() != null) {
            leaderPredicate = ExpressionUtils.and(leaderPredicate, qFruitLeaderPO.inclinationTime.year().eq(dto.getYearNumber()));
        }

        return this.getFruitPsPieceData(dto.getOrgIdList(), leaderPredicate);
    }


    public long getFruitPsPieceData(Set<Long> orgIds, Predicate leaderPredicate) {
        QOrgPo qOrgPo = QOrgPo.orgPo;
        QFruitPO qFruitPO = QFruitPO.fruitPO;
        QFruitOrgRelPo qFruitOrgRelPo = QFruitOrgRelPo.fruitOrgRelPo;
        QFruitLeaderPO qFruitLeaderPO = QFruitLeaderPO.fruitLeaderPO;

        Set<Long> fruitIdList = new HashSet<>();
        jpaQueryFactory.select(qFruitLeaderPO.fruitId, qFruitLeaderPO.inclinationLevel.min())
                .from(qFruitLeaderPO).where(leaderPredicate).groupBy(qFruitLeaderPO.fruitId).fetch()
                .stream().forEach(tuple -> {
            fruitIdList.add(tuple.get(qFruitLeaderPO.fruitId));
        });

        Predicate predicate = qFruitPO.id.isNotNull().and(qFruitPO.isDel.isFalse()).and(qFruitPO.isPublic.eq("0")
                .and(qFruitPO.type.eq(ComConstant.FruitType.InternalReferenceReport)));

        long psFruitCount = jpaQueryFactory.select(qFruitOrgRelPo.fruitId)
                .from(qOrgPo)
                .leftJoin(qFruitOrgRelPo).on(qFruitOrgRelPo.orgId.eq(qOrgPo.id)
                        .and(qFruitOrgRelPo.status.eq(ComConstant.FruitStatus.APPROVED)))
                .leftJoin(qFruitPO).on(qFruitPO.id.eq(qFruitOrgRelPo.fruitId))
                .where(qOrgPo.deleted.isFalse().and(predicate).and(qFruitOrgRelPo.fruitId.in(fruitIdList)))
                .where(qOrgPo.id.in(orgIds))
                .fetchCount();

        return psFruitCount;

    }

    @Override
    public void createFruitWxAppletSimple(FruitWxAppletPO po) {
        fruitWxAppletRepository.save(po);
    }
}
